我目前正在使用 OpenXml 手动构建 Excel 文件。我正在添加工作表,但是,我遇到了一个问题。我有一个循环添加每张工作表的名称但是一旦它运行并且我尝试打开文件,我收到以下消息:
"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."
我认为问题可能是因为我使用字符串变量添加了每张工作表的名称。当我取出它并添加其他东西时,它起作用了。下面是我循环访问并添加工作表的代码。
//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++;
}
我看到有人提到,单元格中的字符串可以转换为字符串是一个问题,但在这种情况下,字符串将始终是字符串。任何帮助将不胜感激。
编辑:我已经找出问题所在。问题是 Name 属性的最大长度为 31。我的一个项目的长度为 42,因此出现错误。我确实找到了一组很棒的代码来验证我的 OpenXml。 Link .
更新: 奇怪的是,有人认为这个问题是关于寻找一些代码来帮助验证我在做什么。不是……问题很明确:为什么我在尝试命名工作表时收到错误消息。虽然我找到了一些验证码,但我并没有要求验证码。
我确实要求,如果你想提供帮助,请阅读问题而不是假设我在问什么,如果你不知道我想回答什么,请问...
最佳答案
为了找出导致此错误的问题,您需要验证生成的文档。
除了使用描述的内置验证方法外 here ,这并没有向您显示我发现的所有问题,我建议您下载并安装 Microsoft's Open XML SDK 2.5 for Microsoft Office .
它包含Microsoft 的 Open XML SDK 2.5 Productivity Tool,在这里非常有用:
创建损坏的 XLSX 文件的副本,并按照 Microsoft Excel 的建议应用修复(假设您有文件
FileName_corrupt.xlsx
和FileName_fixed.xlsx
然后,运行Microsoft's Open XML SDK 2.5 Productivity Tool,打开
FileName_corrupt.xlsx
,选择“比较文件”并指定第二个文件FileName_fixed .xlsx
。这使您可以比较两个文件的 XML 结构。让 Microsoft 的 Open XML SDK 2.5 Productivity Tool 从这两个文件生成 C# 代码:首先打开它们,然后右键单击根级别并选择“反射(reflect)代码”。这将创建允许您生成相同文件的 C# 代码。保存两个 C# 代码版本(即 FileName_corrupt.cs 和 FileName_fixed.cs)
现在您可以通过 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);
}
}
关于c# - 收到有关 Excel 文件内容有问题的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33813411/