web-dev-qa-db-ja.com

OpenXMLでカスタム列幅を作成する(Excel)

私はOpenXML(v。2.5)を初めて使用し、行とセルを作成できますが、列幅を設定できるようにする必要があり、何らかの理由で正しく設定できません。

このコードなし:

        Columns cols = new Columns();

        Column c1 = new Column()
        {
            CustomWidth = true,
            Width = 20
        };

        cols.Append(c1);
        wspart.Worksheet.Append(cols);

プログラムが実行され、Excelファイルが正常に生成されます。

以下のコードは準拠して実行されますが、破損したExcelドキュメントが残ります。列を追加しようとすると、何が悪いのでしょうか?

    public static void createExcel() //TODO change to private
    {
        //create the spreadsheet document with openxml See https://msdn.Microsoft.com/en-us/library/office/ff478153.aspx
        SpreadsheetDocument spreadsheetDoc = SpreadsheetDocument.Create(@"C:\Users\Reid\Documents\BLA\test.xlsx", SpreadsheetDocumentType.Workbook); //TODO change path

        //add a workbook part
        WorkbookPart wbpart = spreadsheetDoc.AddWorkbookPart();
        wbpart.Workbook = new Workbook();

        //add a worksheet part
        WorksheetPart wspart = wbpart.AddNewPart<WorksheetPart>();
        Worksheet ws = new Worksheet(new SheetData());
        wspart.Worksheet = ws;

        //create a new sheets array
        Sheets sheets = spreadsheetDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

        //create a new sheet
        Sheet sheet = new Sheet()
        {
            Id = spreadsheetDoc.WorkbookPart.GetIdOfPart(wspart),
            SheetId = 1,
            Name = "mySheet" //TODO change name
        };

        //add the sheet to the workbook sheet aray
        sheets.Append(sheet);

        SheetData shData = wspart.Worksheet.GetFirstChild<SheetData>();

        //////////////////////////////////row and col widths//////////////////////
        Columns cols = new Columns();

        Column c1 = new Column()
        {
            CustomWidth = true,
            Width = 20
        };

        cols.Append(c1);
        wspart.Worksheet.Append(cols);

        //create the first row
        Row r1 = new Row
        {
            RowIndex = 1,
            CustomHeight = true,
            Height = 71.25 //change height based on info
        };
        shData.Append(r1);
  ////////////////////////cell data/////////////////////////////////

        // In the new row, find the column location to insert a cell in A1.
        Cell refCell = null;
        foreach (Cell cell in r1.Elements<Cell>())
        {
            if (string.Compare(cell.CellReference.Value, "A1", true) > 0)
            {
                refCell = cell;
                break;
            }
        }
        // Add the cell to the cell table at A1.
        Cell newCell = new Cell() {
            CellReference = "A1",
        };
        r1.InsertBefore(newCell, refCell);

        // Set the cell value to be a numeric value of 100.
        newCell.CellValue = new CellValue("100");


        //TODO add in standard things (text that is always the same, headers, logos, etc.)

        //TODO add in dynamic text

        //TODO create and add in barcodes

        //Save and close the document
        wbpart.Workbook.Save();
        spreadsheetDoc.Close();

        //TODO send document to database
    }
11
Reid

あなたが遭遇している問題は、新しい列要素を作成して既存のワークシートのコンテンツに追加することだと思います。新しい列を既存の列要素に追加する必要があると思います。

ワークブックを作成して保存し、空の列にコンテンツを追加してから、ワークブックを新しい名前で保存して閉じました。

Open XML SDK 2.5 Productivity Toolの "比較"機能を使用して、違いを含むワークシートパーツを選択し、それを選択して、[パッケージコードの表示]をクリックしました。元のファイルから新しい列を含む変更されたファイルを生成するコードは私を示しています:

Columns columns1=worksheet1.GetFirstChild<Columns>();
//other code here
Column column1 = new Column(){ Min = (UInt32Value)5U, Max = (UInt32Value)5U, Width = 16D, CustomWidth = true };
columns1.Append(column1);

新しい列の列範囲も指定する必要があるようです。

6
Cindy Meister

上記の選択された答えは私の問題を解決しませんでしたが、私は最終的にそれを理解しました。私の問題は、次の行を呼び出したときです:Columns columns1=worksheet1.GetFirstChild<Columns>();現在ワークシートにColumnsの子がないため、返されたオブジェクトはnullで、列を追加しようとしたときにランタイムエラーが発生しましたColumnsオブジェクトに。

問題は、Excelが非常にうるさいということです。実際のsheet.xmlファイルのcolumns要素は、sheetdata要素の前にある必要があります。カスタム列をワークシートに追加しようとすると、sheetdata要素の後に列要素が配置されるため、ファイルが破損しました。 sheetdata要素の前にある必要があることを知っていたので、それをワークシートの先頭に挿入し、ワークシートに追加する必要はありませんでした。これが私のために働いたコードです:

// Save the stylesheet formats
stylesPart.Stylesheet.Save();

// Create custom widths for columns
Columns lstColumns = worksheetPart.Worksheet.GetFirstChild<Columns>();
Boolean needToInsertColumns = false;
if (lstColumns == null)
{
    lstColumns = new Columns();
    needToInsertColumns = true;
}
// Min = 1, Max = 1 ==> Apply this to column 1 (A)
// Min = 2, Max = 2 ==> Apply this to column 2 (B)
// Width = 25 ==> Set the width to 25
// CustomWidth = true ==> Tell Excel to use the custom width
lstColumns.Append(new Column() { Min = 1, Max = 1, Width = 25, CustomWidth = true });
lstColumns.Append(new Column() { Min = 2, Max = 2, Width = 9, CustomWidth = true });
lstColumns.Append(new Column() { Min = 3, Max = 3, Width = 9, CustomWidth = true });
lstColumns.Append(new Column() { Min = 4, Max = 4, Width = 9, CustomWidth = true });
lstColumns.Append(new Column() { Min = 5, Max = 5, Width = 13, CustomWidth = true });
lstColumns.Append(new Column() { Min = 6, Max = 6, Width = 17, CustomWidth = true });
lstColumns.Append(new Column() { Min = 7, Max = 7, Width = 12, CustomWidth = true });
// Only insert the columns if we had to create a new columns element
if (needToInsertColumns)
    worksheetPart.Worksheet.InsertAt(lstColumns, 0);

// Get the sheetData cells
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

これが誰かを助けることを願っています!!

20
compman2408