我正在处理一个已经拥有所有公式和格式的Excel文件,我通过添加一个带表格的工作表来向其中添加数据。当我在Excel中打开该文件时,会出现以下错误信息:
虽然手动创建的文件中的单元格看起来像这样。
显然这里有一个差异,但我不知道如何纠正它,也不知道这个差异是否是错误的实际原因。但是,既然其他所有东西看起来都一样,我不知道还能是什么其他原因。
哦,还有几件事情,这个文件不起作用,但我能够使用另一个不包含表格的文件,当我加入表格时,问题就会出现,所以我至少知道这一点。
另外,如果你要建议我使用ClosedXML,请不要这样做。我已经用过它,但它似乎会随机地留下格式问题,我无法弄清楚原因,这就是为什么我转向OpenXML SDK的原因。
以下是一些C#代码。
"Excel完成了文件级别的验证和修复,此工作簿的某些部分可能已被修复或丢失。已删除记录:/xl/worksheets/sheet6.xml 部分的单元格信息"
然而,当我以相同内容手动创建文件并打开时,则不会出现任何问题。 我还发现了Open XML 2.5生产力工具,它可以针对生成的文件运行验证,结果称没有问题。
当我在这两个文件上进行比较时,我发现生成的文件看起来是这样的。
<x:c r="B462" t="inlineStr">
<x:is>
<x:t>1150828</x:t>
</x:is>
</x:c>
虽然手动创建的文件中的单元格看起来像这样。
<c s="80" r="B462">
<v>
1150828
</v>
</c>
显然这里有一个差异,但我不知道如何纠正它,也不知道这个差异是否是错误的实际原因。但是,既然其他所有东西看起来都一样,我不知道还能是什么其他原因。
哦,还有几件事情,这个文件不起作用,但我能够使用另一个不包含表格的文件,当我加入表格时,问题就会出现,所以我至少知道这一点。
另外,如果你要建议我使用ClosedXML,请不要这样做。我已经用过它,但它似乎会随机地留下格式问题,我无法弄清楚原因,这就是为什么我转向OpenXML SDK的原因。
以下是一些C#代码。
dt.Load(reader);
RowCount = dt.Rows.Count;
ColumnCount = dt.Columns.Count;
workbookPart = spreadDoc.WorkbookPart;
SheetDimension sheetDimension = new SheetDimension() { Reference = "A1:" + ColumnLetters[ColumnCount - 1] + (RowCount + 1) };
worksheetPart = Program.GetWorksheetPart(workbookPart, reportStep.ExcelSheetName);
worksheetPart.Worksheet.SheetDimension = sheetDimension;
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => reportStep.ExcelSheetName.Equals(s.Name)).Id;
if (reportStep.ExcelTableExists)
{
TableDefinitionPart tableDef = null;
int looper = 0;
foreach (WorksheetPart wsp in spreadDoc.WorkbookPart.WorksheetParts)
{
if (wsp.TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(reportStep.ExcelTableName)).Count() == 1)
{
tableDef = spreadDoc.WorkbookPart.WorksheetParts.ElementAt(looper).TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(reportStep.ExcelTableName)).FirstOrDefault();
tableDef.Table.Reference.Value = "A1:" + (ColumnLetters[ColumnCount - 1] + (RowCount +1) ).ToString();
tableDef.Table.AutoFilter.Reference.Value = "A1:" + (ColumnLetters[ColumnCount - 1] + (RowCount +1)).ToString();
// tabledefinitionPart = Program.GetTablePart(wsp, reportStep.ExcelTableName, ColumnCount, RowCount);
}
looper++;
}
}
sheetData = Chef.Program.ExportDataTable(dt, sheetData);
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == reportStep.ExcelSheetName);
public static TableDefinitionPart GetTablePart(WorksheetPart worksheet, string tablename, int columnCount, int rowCount)
{
uint CellRange = (uint)(columnCount);
TableColumns tableColumns1 = new TableColumns() { Count = (UInt32Value)(CellRange) };
var tableDefPart = worksheet.TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(tablename)).FirstOrDefault();
//worksheet.WorksheetPart.TableDefinitionParts.AddNewPart<TableDefinitionPart>(tablename);
var table = new Table() { HeaderRowCount = (uint)columnCount, Name = tablename, DisplayName = tablename, Reference = "A1:" + ColumnLetters[columnCount -1] + (rowCount + 1), TotalsRowShown = false };
TableStyleInfo tableStyleInfo1 = new TableStyleInfo()
{
Name = "TableStyleMedium2",
ShowFirstColumn = false,
ShowLastColumn = false,
ShowRowStripes = true,
ShowColumnStripes = false
};
table.Append(tableStyleInfo1);
// table.Append(tableColumns1);
tableDefPart.Table = table;
return tableDefPart;
}
编辑部分,添加所请求的额外方法 更新于9/5/15
我已经删除了添加标题值的代码,因为它们已经是Excel文件基础模板的一部分。还删除了指定单元格数据类型的操作,以保留模板已有的单元格数据类型设置。
public static SheetData ExportDataTable2(System.Data.DataTable exportData, SheetData sheetData)
{
//loop through each data row
DataRow contentRow;
int startRow = 2;
for (int i = 0; i < exportData.Rows.Count; i++)
{
contentRow = exportData.Rows[i];
sheetData.AppendChild(createContentRow(contentRow, i + startRow));
}
return sheetData;
}
private static Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
// cell.DataType = CellValues.Number;
cell.CellReference = getColumnName(columnIndex) + rowIndex;
cell.CellValue = new CellValue(cellValue.ToString());
return cell;
}
private static Row createContentRow(DataRow dataRow, int rowIndex)
{
Row row = new Row
{
RowIndex = (UInt32)rowIndex
};
for (int i = 0; i < dataRow.Table.Columns.Count; i++)
{
Cell dataCell = createTextCell(i + 1, rowIndex, dataRow[i]);
// dataCell.DataType = CellValues.SharedString;
row.AppendChild(dataCell);
}
return row;
}
Chef.Program.ExportDataTable
方法的代码吗?你列出的 XML 看起来不错,生成的 XML 使用的是内联字符串,而手动创建的则使用了 共享字符串表。 - petelids