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

Iya*_*sho 3 c# rendering openxml xlsx openxml-sdk

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

“我们发现‘FileName.xlsx’中的某些内容存在问题。您希望我们尽力恢复吗?如果您信任此工作簿的来源,请单击“是”。”

我认为问题可能是由于我使用字符串变量添加了每个工作表的名称。当我把它拿出来并添加其他东西时,它就起作用了。下面是我的代码,我在其中循环并添加我的工作表。

//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++;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我已经解决了这个问题。问题是“名称”属性的最大长度为 31。我的其中一项的长度为 42,因此出现错误。我确实找到了一组很酷的代码来验证我的 OpenXml。 关联

更新:奇怪的是,有人认为这个问题是关于寻找一些代码来帮助验证我正在做的事情。这不是......问题很清楚:为什么我在尝试命名工作表时收到错误。我并没有要求验证码,尽管我找到了一些。

我确实要求,如果您想提供帮助,请阅读问题而不是假设我在问什么,如果您不知道我希望回答什么,请询问...

Mat*_*att 5

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

除了使用此处描述的内置验证方法(该方法不会向您显示我发现的所有问题)之外,我建议您下载并安装Microsoft 的 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. 然后,运行Microsoft的Open XML SDK 2.5 Productivity Tool,打开FileName_corrupt.xlsx,选择“比较文件”并指定第二个文件FileName_fixed.xlsx。这允许您比较两个文件的 XML 结构。

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

  4. 现在您可以通过 Visual Studio 比较差异:要么使用
    devenv.exe /diff FileName_corrupt.cs FileName_fixed.cs
    它们进行比较,要么使用我创建的批处理文件来启动 VS 比较- 这是 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();
        }
Run Code Online (Sandbox Code Playgroud)

随着

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

通过稍加修改,您也可以轻松使用上面的代码进行Microsoft Word验证:

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