【问题标题】:OpenXML (SAX Method) - Adding row to existing tabOpenXML(SAX 方法) - 将行添加到现有选项卡
【发布时间】:2013-01-10 17:43:16
【问题描述】:

我正在尝试使用 OpenXML(SAX 方法)创建 Excel 文档。当我的方法被调用时,我想检查是否已经为给定的键创建了一个选项卡。如果是,我只想在该选项卡的底部附加一行。如果尚未为给定键创建选项卡,我将创建一个新选项卡,例如;

      part = wbPart.AddNewPart<WorksheetPart>();

                        string worksheetName = row.Key[i].ToString();

                        Sheet sheet = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(part), SheetId = sheetNumber, Name = worksheetName };
                        sheets.Append(sheet);

                        writer = OpenXmlWriter.Create(part);
                        writer.WriteStartElement(new Worksheet());
                        writer.WriteStartElement(new SheetData());

                        currentrow = 1;

                        string header = Header + "\t" + wrapper.GetHeaderString(3, 2, -1); //need to fix
                        WriteDataToExcel(header, currentrow, 0, writer);
                        currentrow++;


                        writer.WriteEndElement();
                        writer.WriteEndElement();
                        writer.Close();

如果已经创建了一个选项卡,我会使用以下代码回忆工作表;

private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
    {
        IEnumerable<Sheet> sheets =
           document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
           Elements<Sheet>().Where(s => s.Name == sheetName);

        if (sheets.Count() == 0)
        {
            // The specified worksheet does not exist.

            return null;
        }

        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)
             document.WorkbookPart.GetPartById(relationshipId);
        return worksheetPart;

    }

当返回正确的工作表部分时,我尝试通过将我的 OpenXmlWriter 指向正确的部分然后添加行来添加新行;

   part = GetWorksheetPartByName(document, row.Key[i].ToString());

                        writer = OpenXmlWriter.Create(part);
                        writer.WriteStartElement(part.Worksheet);
                        writer.WriteStartElement(part.Worksheet.GetFirstChild<SheetData>());
                        SheetData sheetData = part.Worksheet.GetFirstChild<SheetData>();
                        Row lastRow = sheetData.Elements<Row>().LastOrDefault();

代码会运行,但是我总是只得到一行(我第一次创建选项卡时添加的第一行)。电子表格中不显示任何后续行。

我将添加很多行(超过 50,000 行),并且不希望每次都创建新文件并复制信息。

【问题讨论】:

标签: c# excel openxml sax


【解决方案1】:

根据我的经验,使用 SAX 方法编写(即使用 OpenXmlWriter)最适合新事物(部件、工作表等)。当您使用 OpenXmlWriter.Create() 时,这就像覆盖部件(在本例中为 WorksheetPart)的原始现有数据。即使实际上,它不是。很复杂。

就我的实验而言,如果有现有数据,则无法使用 OpenXmlWriter 编辑数据。即使您使用 Save() 函数或正确关闭 OpenXmlWriter 也不行。出于某种原因,SDK 会忽略您的努力。因此,您添加的原始一行。

如果您要写入 50,000 行,最好一次性完成。那么 SAX 方法将很有用。此外,如果您只写一行(一次?),使用 SAX 与 DOM 方法相比,速度优势可以忽略不计。

【讨论】:

  • 我一次写一行。我一直在寻找,就像你说的那样,我认为速度优势并没有真正存在,所以现在我正在研究一种 DOM 方法。谢谢。
  • @Vincent :对我很有帮助的答案。我正在努力解决类似的问题,请您帮忙。我正在用 SAX 方法编写 Excel 文件。我希望合并一些标题单元格。搜索了很多,但只有通过 DOM 方法才能合并单元格。所以现在我在 SAX 中编写完整的 excel,在 DOM 方法中再次打开它,合并后我正在保存它。对于较少的记录,它可以正常工作,但是当记录数很高时,它会出现内存不足的异常。有什么方法可以实现功能吗?请回复stackoverflow.com/q/29845898/3103066
【解决方案2】:

根据本站work with exist Excel with OpenXMLWriter: OpenXMLWriter 只能操作一个新的 Worksheet 而不是一个现有的文档。所以恐怕你不能使用 OpenXMLWriter 将值插入到现有电子表格的特定单元格中。

您可以读取现有 Excel 文件中的所有数据,然后似乎您需要添加行(50,000+)我建议使用 openxmlwriter 将新旧数据一次写入新的 Excel 文件。如果您使用 DOM 方法,则在追加大量行(50,000+)后可能会导致内存问题。

【讨论】:

    猜你喜欢
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多