繁体   English   中英

使用DocumentFormat.OpenXML创建的Excel文件(.xlsx)在Excel打开时需要修复

[英]Excel file (.xlsx) created by using DocumentFormat.OpenXML needs to be repaired when opening in Excel

我有一种方法可以使用 DocumentFormat.OpenXml 从字符串列表中创建 excel 文件 (.xlsx)。 当我尝试使用 Excel 2016 打开创建的文件时,需要修复它。当我单击“是”时,Excel 正确显示了我的文件。 有没有人有什么建议? 提前致谢。

这是我的代码:

private byte[] ExportDataXlsx(System.Data.Common.DbDataReader reader, string[] fields, string[] headers, string Culture) {
  System.IO.MemoryStream sw = new System.IO.MemoryStream();
  using (var workbook = Packaging.SpreadsheetDocument.Create(sw, SpreadsheetDocumentType.Workbook)) {
      
      var sheetData = CreateSheet(workbook);

      while (reader.Read()) {
          Spreadsheet.Row newRow = new Spreadsheet.Row();
          foreach (string column in fields) {
              Spreadsheet.Cell cell = new Spreadsheet.Cell();
              cell.DataType = Spreadsheet.CellValues.String;
              object value = null;
              try {
                  int index = reader.GetOrdinal(column);
                  cell.DataType = DbKymosDomainService.ToXlsType(reader.GetFieldType(index));

                  value = DbKymosDomainService.ToStringFromCulture(reader.GetValue(index), reader.GetFieldType(index), Culture);
                  if (cell.DataType == Spreadsheet.CellValues.Number){
                      value = value == null ? "" : value.ToString().Replace(",", ".");
                  }
              }
              catch { }
              cell.CellValue = new Spreadsheet.CellValue(value == null ? null : value.ToString()); //
              newRow.AppendChild(cell);
              try { var x = newRow.InnerXml; } catch { newRow.RemoveChild(cell); }
          }

          sheetData.AppendChild(newRow);
      }

      workbook.Close();
  }

  byte[] data = sw.ToArray();
  sw.Close();
  sw.Dispose();

  return data;
}

Function 创建表:

private Spreadsheet.SheetData CreateSheet(Packaging.SpreadsheetDocument workbook)
{
    var workbookPart = workbook.AddWorkbookPart();

    workbook.WorkbookPart.Workbook = new Spreadsheet.Workbook();

    workbook.WorkbookPart.Workbook.Sheets = new Spreadsheet.Sheets();

    var sheetPart = workbook.WorkbookPart.AddNewPart<Packaging.WorksheetPart>();
    var sheetData = new Spreadsheet.SheetData();
    sheetPart.Worksheet = new Spreadsheet.Worksheet(sheetData);

    Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Spreadsheet.Sheets>();
    string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

    uint sheetId = 1;
    if (sheets.Elements<Spreadsheet.Sheet>().Count() > 0) {
        sheetId =
            sheets.Elements<Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
    }

    Spreadsheet.Sheet sheet = new Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = "Export" };
    sheets.Append(sheet);

    return sheetData;
}

根据我的经验,当使用 OpenXML 创建文件后需要对其进行修复时,这意味着它缺少关键元素或关键元素位于错误的位置。 我在遵循您的代码时遇到了困难,因此这本身就表明某些东西在错误的地方。 代码应该是顺序的和不言自明的。 然而,一些提示可以帮助您找到问题的根本原因。

我建议首先使用 ClosedXML,因为它需要大量的编码压力。 https://github.com/closedxml/closedxml

调试您的代码并逐步执行每个步骤以查看发生了什么。

在 OpenXML Productivity Tool https://github.com/OfficeDev/Open-XML-SDK/releases/tag/v2.5中打开创建的文件并查看一下。

我不能没有的另一个工具是 OpenXML FileViewer: https://github.com/davecra/OpenXmlFileViewer

最后,我总是运行这个子例程来验证我使用 OpenXML 创建的文档:

    public static List<string> ValidateWordDocument(FileInfo filepath, ref Int32 maxerrors = 100)
{
    try
    {
        using (WordprocessingDocument wDoc = WordprocessingDocument.Open(filepath.FullName, false))
        {
            OpenXmlValidator validator = new OpenXmlValidator();
            int count = 0;
            List<string> er = new List<string>()
            {
                string.Format($"Assessment of {filepath.Name} on {DateTime.Now} yielded the following result:  {Constants.vbCrLf}")
            };

            // set at zero so that we can determine the total quantity of errors
            validator.MaxNumberOfErrors = 0;
            // String.Format("<strong> Warning : </strong>")
            foreach (ValidationErrorInfo error in validator.Validate(wDoc))
            {
                count += 1;
                if (count > maxerrors)
                    break;
                er.Add($"Error {count}{Constants.vbCrLf}" +  $"Description {error.Description}{Constants.vbCrLf}" + $"ErrorType:  {error.ErrorType}{Constants.vbCrLf}" + $"Node {error.Node}{Constants.vbCrLf}" + $"Name {error.Node.LocalName}{Constants.vbCrLf}" + $"Path {error.Path.XPath}{Constants.vbCrLf}" + $"Part: {error.Part.Uri}{Constants.vbCrLf}" + $"-------------------------------------------{Constants.vbCrLf}" + $"Outer XML: {error.Node.OuterXml}" + $"-------------------------------------------{Constants.vbCrLf}");
            }
            int validatorcount = validator.Validate(wDoc).Count;

            switch (validatorcount)
            {
                case object _ when validatorcount > maxerrors:
                    {
                        er.Add($"Returned {count - 1} as this is the Maximum Number set by the system. The actual number of errors in {filepath.Name} is {validatorcount}");
                        er.Add("A summary list of all error types encountered is given below");

                        List<string> expectedErrors = validator.Validate(wDoc).Select(_e => _e.Description).Distinct().ToList();
                        er.AddRange(expectedErrors);
                        break;
                    }

                case object _ when 1 <= validatorcount && validatorcount <= maxerrors:
                    {
                        er.Add($"Returned all {validator}  errors in {filepath.Name}");
                        break;
                    }

                case object _ when validatorcount == 0:
                    {
                        er.Add($"No Errors found in document {filepath.Name}");
                        break;
                    }
            }

            return er;

            wDoc.Close();
        }
    }
    catch (Exception ex)
    {
        Information.Err.MessageElevate();
        return null;
    }
}

它极大地有助于解决任何潜在问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM