简体   繁体   English

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

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

I have a method which create an excel file (.xlsx) from a list of strings using DocumentFormat.OpenXml.我有一种方法可以使用 DocumentFormat.OpenXml 从字符串列表中创建 excel 文件 (.xlsx)。 The created file needs to be repaired when I try to open it with Excel 2016. When I click "Yes" Excel shows my file correctly.当我尝试使用 Excel 2016 打开创建的文件时,需要修复它。当我单击“是”时,Excel 正确显示了我的文件。 Does anyone have any suggestions?有没有人有什么建议? Thanks in advance.提前致谢。

Here's my code:这是我的代码:

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 which create sheet: 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;
}

In my experience when a file needs to be repaired after creating it using OpenXML it means that it is missing a crucial element or the crucial element is in the wrong place.根据我的经验,当使用 OpenXML 创建文件后需要对其进行修复时,这意味着它缺少关键元素或关键元素位于错误的位置。 I'm having difficulty following your code so that in itself points to something being in the wrong place.我在遵循您的代码时遇到了困难,因此这本身就表明某些东西在错误的地方。 Code should be sequential and self-explanatory.代码应该是顺序的和不言自明的。 A few pointers however to help with getting to the root cause of your issue.然而,一些提示可以帮助您找到问题的根本原因。

I would suggest first using ClosedXML as it takes so much strain out of the coding.我建议首先使用 ClosedXML,因为它需要大量的编码压力。 https://github.com/closedxml/closedxml https://github.com/closedxml/closedxml

Debug your code and step through each step to see what's going on.调试您的代码并逐步执行每个步骤以查看发生了什么。

Open the created file in OpenXML Productivity Tool https://github.com/OfficeDev/Open-XML-SDK/releases/tag/v2.5 and have a look around.在 OpenXML Productivity Tool https://github.com/OfficeDev/Open-XML-SDK/releases/tag/v2.5中打开创建的文件并查看一下。

Another tool that I couldn't be without is OpenXML FileViewer: https://github.com/davecra/OpenXmlFileViewer我不能没有的另一个工具是 OpenXML FileViewer: https://github.com/davecra/OpenXmlFileViewer

Lastly I always run this sub routine to validate documents I create using OpenXML:最后,我总是运行这个子例程来验证我使用 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;
    }
}

It helps greatly with problem solving any potential issues.它极大地有助于解决任何潜在问题。

暂无
暂无

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

相关问题 Excel文件是使用DocumentFormat.OpenXML创建的,但是在Excel中运行时需要修复 - The excel file is created by using DocumentFormat.OpenXML but need to repairing when opeing in Excel 使用Documentformat.OpenXML在C#中验证Excel文件 - Validate Excel file in c# using Documentformat.OpenXML 使用Microsoft DocumentFormat.OpenXml SDK在C#中读取Excel文件 - Reading excel file in c# using Microsoft DocumentFormat.OpenXml SDK 如何使用DocumentFormat.OpenXml C#获取excel工作表中的特定列? - How can I get the specific column in excel worksheet using DocumentFormat.OpenXml C#? 如何使用 C# 和 DocumentFormat.OpenXml nuget ZEFE90A8E604A7C84A70E8 格式化 Excel 中的数字 - How to format number in Excel by using C# and DocumentFormat.OpenXml nuget package? 如何使用 DocumentFormat.OpenXML 或 ClosedXML C# 从 Excel 获取合并单元格 - How to get a merged cell from Excel using DocumentFormat.OpenXML or ClosedXML C# 使用DocumentFormat.OpenXml导出带有页脚的DocX文件 - Export DocX file with Footer using DocumentFormat.OpenXml 使用DocumentFormat.OpenXml dll读取.Doc文件 - Reading .Doc File using DocumentFormat.OpenXml dll DocumentFormat.OpenXml 2.8 版在使用 MergeField 时不起作用 - DocumentFormat.OpenXml Version 2.8 not working when using MergeField OpenXML / DocumentFormat.OpenXml用文字将Excel设置为MailMerge的数据源(字母系列) - OpenXML/DocumentFormat.OpenXml set excel as DataSource for MailMerge in word (Letter series)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM