收到 Excel 文件内容有问题的消息

Receiving message of issue with content in Excel File

我目前正在使用 OpenXml 手动构建一个 Excel 文件。我正在添加 sheets,但是,我遇到了一个问题。我有一个循环添加每个 sheet 的名称,但是一旦它运行并且我尝试打开文件,我收到以下消息:

"We found a problem with some content in 'FileName.xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook, Click Yes."

我认为问题可能是因为我使用字符串变量添加了每个 sheet 的名称。当我取出它并添加其他东西时,它起作用了。下面是我循环并添加 sheets.

的代码
//Technology Areas
foreach (DataRow dr in techAreaDS.Rows)
{
     var data = dr["TechAreaName"].ToString().Split('-');
     var techArea = data[2].TrimStart();

     var techAreaSheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), 
                                     SheetId = sheetId, Name = techArea };
     sheets.Append(techAreaSheet);
     sheetId++;
}

我看到有人提到单元格中的字符串可以转换为字符串是一个问题,但在这种情况下,字符串将始终是字符串。任何帮助将不胜感激。

编辑:我已经解决了问题。问题是名称 属性 的最大长度为 31。我的一个项目的长度为 42,因此出现错误。我确实找到了一组很棒的代码来验证我的 OpenXml。 Link.

更新: 奇怪的是,有人认为这个问题是关于寻找一些代码来帮助验证我在做什么。不是...问题很明确:为什么我在尝试命名 sheets 时收到错误消息。我不是要验证码,虽然我找到了一些。

我确实想问,如果你想帮忙,请阅读问题而不是假设我在问什么,如果你不知道我想回答什么,请问...

我找到问题了。问题是名称 属性 的最大长度为 31 个字符。我尝试使用的文本有时会超过该限制(一个有 42 个字符)。我还找到了一组非常酷的代码来验证我的 Open Xml 以找出具体问题是什么。 Link

为了找出导致此错误的问题,您需要验证生成的文档。

除了使用 here, which doesn't show you all issues as I found out, I suggest that you download and install Microsoft's Open XML SDK 2.5 for Microsoft Office 中描述的内置验证方法。

它包含 Microsoft 的 Open XML SDK 2.5 Productivity Tool,在这里很有帮助:

  1. 创建损坏的 XLSX 文件的副本,并按照 Microsoft Excel 的建议应用修复(假设您有文件 FileName_corrupt.xlsxFileName_fixed.xlsx

  2. 然后,运行 微软的打开XML SDK 2.5 Productivity Tool,打开FileName_corrupt.xlsx,select "Compare Files" 并指定第二个文件 FileName_fixed.xlsx。这允许您比较两个文件的 XML 结构。

  3. Microsoft's Open XML SDK 2.5 Productivity Tool从两个文件生成C#代码:先打开它们,然后右键单击根级别和 select "Reflect Code"。这将创建允许您生成相同文件的 C# 代码。保存两个 C# 代码版本(即 FileName_corrupt.cs 和 FileName_fixed.cs)

  4. 现在你可以通过Visual Studio比较差异:要么使用
    devenv.exe /diff FileName_corrupt.cs FileName_fixed.cs
    比较它们,或使用 batch file I've created to launch the VS compare - 这是 Visual Studio 中的隐藏功能,它允许比较 2 个不属于 TFS 的本地文件。

这样您应该能够找出差异并修复您的代码。


注意:对于第一次验证,我建议使用验证码。仅当仍然失败时,才使用上述步骤。您可以使用

进行验证
   public static string ValidateOpenXmlDocument(OpenXmlPackage pXmlDoc, bool throwExceptionOnValidationFail=false)
    {
        using (var docToValidate = pXmlDoc)
        {
            var validator = new DocumentFormat.OpenXml.Validation.OpenXmlValidator();
            var validationErrors = validator.Validate(docToValidate).ToList();
            var errors = new System.Text.StringBuilder();
            if (validationErrors.Any())
            {
                var errorMessage = string.Format("ValidateOpenXmlDocument: {0} validation error(s) with document", validationErrors.Count);
                errors.AppendLine(errorMessage);
                errors.AppendLine();
            }

            foreach (var error in validationErrors)
            {
                errors.AppendLine("Description: " + error.Description);
                errors.AppendLine("ErrorType: " + error.ErrorType);
                errors.AppendLine("Node: " + error.Node);
                errors.AppendLine("Path: " + error.Path.XPath);
                errors.AppendLine("Part: " + error.Part.Uri);
                if (error.RelatedNode != null)
                {
                    errors.AppendLine("Related Node: " + error.RelatedNode);
                    errors.AppendLine("Related Node Inner Text: " + error.RelatedNode.InnerText);
                }
                errors.AppendLine();
                errors.AppendLine("==============================");
                errors.AppendLine();
            }

            if (validationErrors.Any() && throwExceptionOnValidationFail)
            {
                throw new Exception(errors.ToString());
            }
            if (errors.Length > 0)
            {
                System.Diagnostics.Debug.WriteLine(errors.ToString());
            }
            return errors.ToString();
        }

连同

public static void ValidateExcelDocument(string fileName)
{
    using (var xlsx = SpreadsheetDocument.Open(fileName, true))
    {
        ValidateOpenXmlDocument(xlsx);
    }
}

稍微修改一下,您也可以轻松地将上面的代码用于 Microsoft Word 验证:

public static void ValidateWordDocument(string fileName)
{
    using (var docx = WordprocessingDocument.Open(fileName, true))
    {
        ValidateOpenXmlDocument(docx);
    }
}