修复记录:从头开始创建的工作表中的单元信息

时间:2012-02-22 19:21:02

标签: c# xml excel openxml spreadsheet

打开OpenXML创建的电子表格时收到错误。错误如下。

Repaired Records: Cell information from /xl/worksheets/sheet.xml part
Repaired Records: Cell information from /xl/worksheets/sheet2.xml part
Repaired Records: Cell information from /xl/worksheets/sheet3.xml part

我唯一能在网上找到有用的东西就是这个问题讨论了一种算法,它会多次改变单个细胞导致问题。话虽如此,我将把我的构造函数链接到SpreadsheetDocument以及更新单元格的三个函数(我曾做过一次)。

我可以根据需要提供任何其他功能,但我相信问题出现在下面列出的两个中。

顺便说一下,

 GetWorksheetPartByName
 InsertCellInWorksheet
 GetCell

应该按预期工作。

实际计划

static void Main(string[] args)
    {
        //Full path for File
        const string newFile = "@C:\test.xlsx";

        //Constructor creates default worksheet called "mySheet"
        var spreadsheet = new XLSXHelper(newFile);

        //updating some cells.
        spreadsheet.UpdateCell("mySheet", "D2", "R", 2);
    }

构造

    public XLSXHelper(string filepath)
    {
        newFile = filepath;
        spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
        this.workbookPart = spreadsheetDocument.AddWorkbookPart();
        workbookPart.Workbook = new Workbook();
        this.worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
        worksheetPart.Worksheet = new Worksheet(new SheetData());
        Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
        AppendChild<Sheets>(new Sheets());
        Sheet sheet = new Sheet()
        {
            Id = spreadsheetDocument.WorkbookPart.
                GetIdOfPart(worksheetPart),
            SheetId = 1,
            Name = "mySheet"
        };
        sheets.Append(sheet);
        workbookPart.Workbook.Save();
        spreadsheetDocument.Close();
    }

更新单元格

    public void UpdateCell(string worksheetName, string textToInsert, string columnName, uint rowIndex)
    {
        using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(newFile, true))
        {
            WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, worksheetName);
            if (worksheetPart != null)
            {
                InsertCellInWorksheet(columnName, rowIndex, worksheetPart);
                Cell cell = GetCell(worksheetPart.Worksheet,columnName, rowIndex);
                cell.CellValue = new CellValue(textToInsert);
                worksheetPart.Worksheet.Save();
            }
        }
    }

10 个答案:

答案 0 :(得分:57)

如果要向单元格而不是数字(或可以转换为数字的字符串)添加字符串,则应使用内联字符串或共享字符串而不是CellValue。如果值为数字,则只能使用CellValue。

使用CellValue时生成的XML类似于:

<x:row>
  <x:c>
    <x:v>12345</x:v>
  </x:c>
</x:row>

当您使用内联字符串时,它看起来像:

<x:row>
  <x:c t="inlineStr">
    <x:is>
      <x:t>Foo</x:t>
    </x:is>
  </x:c>
</x:row>

注意内联字符串的“is”节点,并且单元格类型属性设置为“inlineStr”。

以下是为包含文本的单元格生成正确XML的C#代码:

cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString() { Text = new Text(textToInsert) };

从我使用共享字符串读取的内容是可取的,但使用内联字符串可以避免错误,并且在Excel中打开文件时看起来很好。

答案 1 :(得分:9)

我意识到这是一个旧线程,但我刚刚为编程生成的Excel工作表弹出了相同的错误消息。我的问题是我一直在设置工作表的名称,其名称中包含正斜杠。

希望这可以帮助那些偶然发现这个主题的人,因为它是该主题中最受欢迎的主题。

答案 2 :(得分:2)

另一个较晚的 - 但检查你如何将行添加到行中。你有没有剪切和粘贴添加单元格代码,其中有一个简单的&#39;与行中现有的单元格引用(A1等)进行比较?在这种情况下,如果您有一个超出Z - AA1列的单元格 - 那么您最终可能会尝试在单元格B1之前插入单元格(例如)AB1)。然后,您在excel中打开书面工作表时会收到此错误。相反,如果只是沿着每一行向单元格添加单元格,只需直接插入,然后将参考单元格设置为null - 即。添加新单元格结束。

希望这是有道理的。

答案 3 :(得分:1)

我自己偶然发现了这个问题并找到了这个帖子。我案件的差异无法修复文件。 问题是行索引,我将其传递给InsertCellInWorksheet taken from example on MSDN

Cell cell = InsertCellInWorksheet("A", lastRow.RowIndex, worksheetPart);

插入行时,请确保该行的索引为1,而不是0.但{0}为SheetData集合。

sheetData.InsertAt(new Row() { RowIndex = 1 }, 0);
lastRow = sheetData.Elements<Row>().LastOrDefault();

希望能节省一些经历同样麻烦的时间。

有趣的是,我的集成测试通过了,然而,当通过Excel打开文件时,它显示了有关损坏的弹出窗口。似乎有一行索引为0,但是,由于您无法使用Excel打开文件,因此会有点隐秘。

答案 4 :(得分:1)

添加潜在解决方案列表(Year2017 :)):

我遇到了这个问题,因为我没有使用正确的工作簿对象来写入FileOutputStream。

希望这有助于某人。

答案 5 :(得分:0)

这是一个旧线程,但是我遇到了同样的问题,对于像我这样的人来说,找到这个答案可能是有用的:)

我的问题是我的应用程序具有导出模块,并且从一种环境中导出的文件运行良好,但是从另一种环境中却不能。这是同样的错误:

Repaired Records: Cell information from /xl/worksheets/sheet19.xml part

经过深入调查,我发现对于此工作表中的一条记录,它超出了单元格限制32767个字符(excel限制),并且通过直接减少DB上文本的大小,解决了问题。 :)

我希望它会有所帮助:)

答案 6 :(得分:0)

就我而言,SSRS占位符属性具有自定义编号。

修复:

  1. 在SSRS设计器中一对一地进入所有领域。
  2. 查看是否有来自后端的任何字母数字值。 (将您的数据集与SSRS报告中的所有单元格进行交叉比较。
  3. 双击该字段->转到“数字”标签
  4. 点击默认->确定

谢谢 乌玛坎特·尼利格(Emakanth Nelige)

答案 7 :(得分:0)

就我而言,某些单元格具有无穷大的双值。 Excel 给出了不可读的内容错误。 Open XML 生产力工具不会检测到错误,因此很难检测到原因。如果单元格值有可能为无穷大,则应在分配单元格值之前将该值转换为字符串。

答案 8 :(得分:0)

我遇到了同样的问题,如果您的值被存储为共享字符串,您需要在共享字符串表中创建一个新的 id(索引)。

InsertSharedStringItem 函数的实现如下: https://docs.microsoft.com/en-us/office/open-xml/working-with-the-shared-string-table

InsertCellInWorksheet 的实现如下:https://docs.microsoft.com/en-us/office/open-xml/how-to-insert-text-into-a-cell-in-a-spreadsheet#sample-code

这些是示例函数,因此请根据需要更新它们。

var sstid = InsertSharedStringItem(textToInsert, sharedStringTable);
Cell cell = InsertCellInWorksheet(columnName, rowIndex, worksheetPart);
cell.CellValue = new CellValue($"{sstid}");
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
worksheetPart.Worksheet.Save();

答案 9 :(得分:0)

我认为这个话题仍然很活跃..2021年 我的麻烦 - 十进制数的序列化,我们使用十进制逗号“,”,但在 excel 文件的 xml 中,无论当前的文化信息如何,它始终使用美国(所以点“。”)。解决方案 - 至少使用包 2.13.001-beta。问题解决了。