[英]The excel file is created by using DocumentFormat.OpenXML but need to repairing when opeing in 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.