2

The code runs, but corrupts my excel document. Any help would be mucho appreciated! I used this as a reference.

    public void AddRow(string fileName, string[] values) {
        using (SpreadsheetDocument doc =
            SpreadsheetDocument.Open(fileName, true)) {
            SharedStringTablePart sharedStringPart =
                GetSharedStringPart(doc);

            WorksheetPart worksheetPart =
                doc.WorkbookPart.WorksheetParts.First();
            uint rowIdx = AppendRow(worksheetPart);

            for (int i = 0; i < values.Length; ++i) {
                int stringIdx = InsertSharedString(values[i],
                    sharedStringPart);

                Cell cell = InsertCell(i, rowIdx, worksheetPart);
                cell.CellValue = new CellValue(stringIdx.ToString());
                cell.DataType = new EnumValue<CellValues>(
                    CellValues.SharedString);

                worksheetPart.Worksheet.Save();
            }
        }
    }

    private SharedStringTablePart GetSharedStringPart(
        SpreadsheetDocument doc) {
        if (doc.WorkbookPart.
            GetPartsCountOfType<SharedStringTablePart>() > 0)
            return doc.WorkbookPart.
                GetPartsOfType<SharedStringTablePart>().First();
        else
            return doc.WorkbookPart.
                AddNewPart<SharedStringTablePart>();
    }

    private uint AppendRow(WorksheetPart worksheetPart) {
        SheetData sheetData = worksheetPart.Worksheet.
            GetFirstChild<SheetData>();

        uint rowIndex = (uint)sheetData.Elements<Row>().Count();

        Row row = new Row() { RowIndex = rowIndex };
        sheetData.Append(row);

        return rowIndex;
    }

    private int InsertSharedString(string s,
        SharedStringTablePart sharedStringPart) {
        if (sharedStringPart.SharedStringTable == null)
            sharedStringPart.SharedStringTable =
                new SharedStringTable();

        int i = 0;

        foreach (SharedStringItem item in
            sharedStringPart.SharedStringTable.
            Elements<SharedStringItem>()) {
            if (item.InnerText == s)
                return i;
            ++i;
        }

        sharedStringPart.SharedStringTable.AppendChild(
            new Text(s));
        sharedStringPart.SharedStringTable.Save();

        return i;
    }

    private Cell InsertCell(int i, uint rowIdx,
        WorksheetPart worksheetPart) {
        SheetData sheetData = worksheetPart.Worksheet.
            GetFirstChild<SheetData>();
        string cellReference = AlphabetMap.Instance[i] + rowIdx;

        Cell cell = new Cell() { CellReference = cellReference };
        Row row = sheetData.Elements<Row>().ElementAt((int)rowIdx);

        row.InsertAt(cell, i);
        worksheetPart.Worksheet.Save();
        return cell;
    }

2 Answers 2

3

Ah, found it. In the InsertSharedString method,

sharedStringPart.SharedStringTable.AppendChild(
        new Text(s));

should be

sharedStringPart.SharedStringTable.AppendChild(
        new SharedStringItem(new Text(s)));
Sign up to request clarification or add additional context in comments.

Comments

1

I realize this is a very old question, but I found/fixed another issue with the original code:

string cellReference = AlphabetMap.Instance[i] + rowIdx;

should be:

string cellReference = AlphabetMap.Instance[i] + (rowIdx + 1);

This way the first CellReference is A1 instead of A0, which causes Excel to crash on opening

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.