web-dev-qa-db-fra.com

Création de largeurs de colonne personnalisées dans OpenXML (Excel)

Je suis nouveau sur OpenXML (v. 2.5), et je peux créer des lignes et des cellules, mais je dois pouvoir définir la largeur de colonne et je ne peux pas le faire correctement pour une raison quelconque.

Sans ce code:

        Columns cols = new Columns();

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

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

Le programme s'exécute et génère un fichier Excel très bien.

Le code ci-dessous est conforme et s'exécute, mais me laisse un document Excel corrompu. Que fais-je de mal lorsque j'essaie d'ajouter des colonnes?

    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

Je pense que le problème que vous rencontrez est de créer et d'ajouter un nouvel élément de colonnes au contenu de la feuille de calcul existante. Je pense que vous devez ajouter la nouvelle colonne à un élément de colonnes existant.

J'ai créé un classeur, l'ai enregistré, ajouté du contenu dans une colonne vide, puis enregistré le classeur sous un nouveau nom et l'ai fermé.

En utilisant la fonction "Comparer" de l'Open XML SDK 2.5 Productivity Tool, j'ai sélectionné la partie de feuille de calcul contenant la différence, je l'ai sélectionnée, puis j'ai cliqué sur "Afficher le code du package". Le code qui génère le fichier modifié avec la nouvelle colonne du fichier d'origine me montre:

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);

Notez qu'il semble que vous deviez également spécifier la plage de colonnes de la nouvelle colonne.

6
Cindy Meister

La réponse sélectionnée ci-dessus n'a pas résolu mon problème, mais je l'ai finalement compris. Le problème pour moi était lorsque j'appelais la ligne: Columns columns1=worksheet1.GetFirstChild<Columns>(); il n'y avait actuellement pas d'enfant Columns dans la feuille de calcul, donc l'objet renvoyé était nul et j'ai eu une erreur d'exécution lorsque j'ai essayé d'ajouter une colonne à l'objet Columns.

Le problème est qu'Excel est extrêmement difficile. L'élément colonnes du fichier sheet.xml réel doit se trouver avant l'élément sheetdata. Essayer d'ajouter mes colonnes personnalisées à la feuille de calcul a entraîné un fichier corrompu car il plaçait l'élément colonnes après l'élément sheetdata. Comme je savais que cela devait être avant l'élément sheetdata, j'ai dû l'insérer au début de la feuille de calcul et ne pas l'ajouter à la feuille de calcul. Voici le code qui a fonctionné pour moi:

// 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>();

J'espère que cela aide quelqu'un !!

20
compman2408