- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在处理一个现有的 Excel 文件,该文件已经包含所有公式和格式,我将数据添加到带有表格的工作表中,然后当我在 Excel 中打开该文件时出现错误
"Excel completed file level validation and repair. Some parts of this workbook may have been repaired or discarded. Removed Records: Cell information from /xl/worksheets/sheet6.xml part"
然后我打开一个手动创建的具有相同内容的文件,它工作得很好。我还发现了 Open XML 2.5 Productivity Tool,当我对生成的文件运行验证时,它说没有发现问题。
当我对这两个文件进行比较时,我看到生成的文件如下所示。
<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;
}
编辑部分添加请求的其他方法更新于 2015 年 9 月 5 日
我确实删除了添加标题值的代码,因为它们已经是 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;
}
最佳答案
好吧,看来你已经使用了下面的例子OpenXML SDK 2.0: Export a DataTable to Excel作为代码的基础。这是创建单元格的原始代码:
private Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
cell.CellReference = getColumnName(columnIndex) + rowIndex;
InlineString inlineString = new InlineString();
Text t = new Text();
t.Text = cellValue.ToString();
inlineString.AppendChild(t);
cell.AppendChild(inlineString);
return cell;
}
您的原始代码除了以下行外完全相同:
cell.DataType = CellValues.String;
看出区别了吗?
然后你把它改成:
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;
}
好的,问题是您没有正确设置cell.DataType
。它需要与单元格内容同步,否则你会从 Excel 中得到这样的错误。在前一种情况下,您将内容设置为 inline string
,但将数据类型设置为 String
。在后面 - 数据类型为 Number
(您是否注释了该行并不重要 - Number
是单元格的默认数据类型)但内容并不总是一个数字(相同的函数用于列标题 - 毕竟,它称为 createTextCell)。
为了解决这个问题,要么使用示例中的原始代码,要么使用以下代码:
private static Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellReference = getColumnName(columnIndex) + rowIndex;
cell.CellValue = new CellValue(cellValue.ToString());
return cell;
}
最后,如果您需要存储共享字符串、数字、日期等,请阅读文档并设置适当的属性。我同意 OpenXml API 不是很直观,但这就是我们所拥有的。
编辑:根据您的评论,您真正的问题似乎并不完全是问题所在。下面是导出具有不同数据类型列的 DataTable
的高性能示例:
public static class ExcelExporter
{
public static void ExportDataTable(DataTable table, SheetData data)
{
var cellFactory = new CellFactory[table.Columns.Count];
for (int i = 0; i < table.Columns.Count; i++)
cellFactory[i] = GetCellFactory(table.Columns[i].DataType);
int rowIndex = 0;
data.AppendChild(CreateHeaderRow(rowIndex++, table));
for (int i = 0; i < table.Rows.Count; i++)
data.AppendChild(CreateContentRow(rowIndex++, table.Rows[i], cellFactory));
}
private static Row CreateHeaderRow(int rowIndex, DataTable table)
{
var row = CreateRow(rowIndex);
for (int i = 0; i < table.Columns.Count; i++)
{
var cell = CreateTextCell(i, rowIndex, table.Columns[i].ColumnName);
row.AppendChild(cell);
}
return row;
}
private static Row CreateContentRow(int rowIndex, DataRow dataRow, CellFactory[] cellFactory)
{
var row = CreateRow(rowIndex);
for (int i = 0; i < dataRow.Table.Columns.Count; i++)
{
var cell = cellFactory[i](i, rowIndex, dataRow[i]);
row.AppendChild(cell);
}
return row;
}
private static Row CreateRow(int index) { return new Row { RowIndex = (uint)index + 1 }; }
private delegate Cell CellFactory(int columnIndex, int rowIndex, object cellValue);
private static CellFactory GetCellFactory(Type dataType)
{
CellFactory factory;
return CellFactoryMap.TryGetValue(dataType, out factory) ? factory : TextCellFactory;
}
private static readonly CellFactory TextCellFactory = CreateTextCell;
private static readonly CellFactory DateCellFactory = CreateDateCell;
private static readonly CellFactory NumericCellFactory = CreateNumericCell;
private static readonly CellFactory BooleanCellFactory = CreateBooleanCell;
private static readonly Dictionary<Type, CellFactory> CellFactoryMap = new Dictionary<Type, CellFactory>
{
{ typeof(bool), BooleanCellFactory },
{ typeof(DateTime), DateCellFactory },
{ typeof(byte), NumericCellFactory },
{ typeof(sbyte), NumericCellFactory },
{ typeof(short), NumericCellFactory },
{ typeof(ushort), NumericCellFactory },
{ typeof(int), NumericCellFactory },
{ typeof(uint), NumericCellFactory },
{ typeof(long), NumericCellFactory },
{ typeof(ulong), NumericCellFactory },
{ typeof(float), NumericCellFactory },
{ typeof(double), NumericCellFactory },
{ typeof(decimal), NumericCellFactory },
};
private static Cell CreateTextCell(int columnIndex, int rowIndex, object cellValue)
{
return CreateCell(CellValues.String, columnIndex, rowIndex, ToExcelValue(cellValue));
}
private static Cell CreateDateCell(int columnIndex, int rowIndex, object cellValue)
{
// NOTE: CellValues.Date is not supported in older Excel version.
// In all Excel versions dates can be stored with CellValues.Number and a format style.
// Since I have no styles, will export them just as text
//var cell = CreateCell(CellValues.Number, columnIndex, rowIndex, ToExcelDate(cellValue));
//cell.StyleIndex = ...;
//return cell;
return CreateCell(CellValues.String, columnIndex, rowIndex,
cellValue != null && cellValue != DBNull.Value ? ((DateTime)cellValue).ToShortDateString() : null);
}
private static Cell CreateNumericCell(int columnIndex, int rowIndex, object cellValue)
{
return CreateCell(CellValues.Number, columnIndex, rowIndex, ToExcelValue(cellValue));
}
private static Cell CreateBooleanCell(int columnIndex, int rowIndex, object cellValue)
{
// NOTE: CellValues.Boolean is not supported in older Excel version
//return CreateCell(CellValues.Boolean, columnIndex, rowIndex, ToExcelValue(cellValue));
return CreateCell(CellValues.String, columnIndex, rowIndex, ToExcelValue(cellValue));
}
private static Cell CreateCell(CellValues dataType, int columnIndex, int rowIndex, string cellValue)
{
var cell = new Cell();
if (dataType != CellValues.Number) cell.DataType = dataType;
cell.CellReference = GetColumnName(columnIndex) + (rowIndex + 1);
cell.CellValue = new CellValue(cellValue ?? string.Empty);
return cell;
}
private static string ToExcelValue(object value)
{
if (value == null || value == DBNull.Value) return null;
return Convert.ToString(value, CultureInfo.InvariantCulture);
}
private static DateTime ExcelBaseDate = new DateTime(1900, 1, 1);
private static string ToExcelDate(object value)
{
const int days29Feb1900 = 59;
if (value == null || value == DBNull.Value) return null;
var date = ((DateTime)value).Date;
var days = (date - ExcelBaseDate).Days + 1;
if (days >= days29Feb1900) days++;
return days.ToString(CultureInfo.InvariantCulture);
}
private static string GetColumnName(int index) { return ColumnNameTable[index]; }
private static readonly string[] ColumnNameTable = BuildColumnNameTable();
private static string[] BuildColumnNameTable()
{
var table = new string[16384];
var sb = new StringBuilder();
for (int i = 0; i < table.Length; i++)
table[i] = sb.BuildColumnName(i);
return table;
}
private static string BuildColumnName(this StringBuilder sb, int index)
{
const int startLetter = 'A';
const int letterCount = 'Z' - startLetter + 1;
sb.Clear();
while (true)
{
var letter = (char)(startLetter + (index % letterCount));
sb.Insert(0, letter);
if (index < letterCount) break;
index = (index / letterCount) - 1;
}
return sb.ToString();
}
}
关键是,不要在处理过程中检查每个值的类型,而是在开始时根据每个列的数据类型准备一个不同的创建单元格方法。
关于c# - OpenXML SDK 2.5 不可读的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32277394/
我正在为我的按钮使用 onClick 功能。我的按钮代码如下所示: Button 1 Button 2 我的 JS 函数如下所示: function fadeNext(selectedId, spee
首先,我想提一下,我理解每个人在不提供至少一些试验或错误的情况下提出问题的感受,但这纯粹是一种知识需求,话虽如此,我会去提前问。 我一直无法弄清楚如何将保存在 MySQL 表中的 600-1000 个
我想做的事情有点令人困惑,而且我英语不太好,所以我先把代码贴在这里,这样你就可以很容易地理解: 以下是表单内容: Testing for Stackoverflow Option1
我学习 SDL 二维编程已有一段时间了,现在我想创建一个结合使用 SDL 和 OpenGL 的程序。我是这样设置的: SDL_Init(SDL_INIT_VIDEO); window = SDL_Cr
我创建了 2 个 data-* 标签。数据类别和数据标签。单击 href 标签后,我想复制该数据类别和数据标签以形成输入。我的代码是:
我想用 CSS 换行。我正在使用内容。 td:before { content: "Test\A Test2"; } 它不工作。如何正确
这个问题已经有答案了: Java Class that implements Map and keeps insertion order? (8 个回答) 已关闭 6 年前。 我有一个 HashMap
我正在尝试使用 JMeter 执行端到端测试。测试涉及写入SFTP文件夹并从另一个SFTP文件夹读取写入操作生成的文件。 我能够使用 JMeter SSH SFTP 插件连接到 SFTP 文件夹,并能
您好,我有带有标准服务器端 Servlet 的 GWT 客户端。 我可以从 GWT 客户端上传文件并在服务器端读取其内容 我可以将其作为字符串发送回客户端 但是 我有 GWT FormPanel与操作
我在 Plone 4.3.9 中创建了一个自定义类型的灵巧性,称为 PersonalPage,必须只允许在特定文件夹中使用 成员文件夹/用户文件夹 . 在他的 FTI 中,默认情况下 False .
在新(更新)版本的应用程序中更改小部件布局的最佳做法是什么?当新版本提供更新、更好的小部件时,如何处理现有小部件? 最佳答案 我认为您必须向用户显示一个弹出窗口,说明“此版本中的新功能”并要求他们重新
在我的应用程序中,我使用支持 View 寻呼机和 PagerTabStrip。进入查看寻呼机我有一些 fragment ,进入其中一个我正在使用支持卡片 View 。运行应用程序后,所有卡片 View
我有以下布局文件。基本上我有谷歌地图,在左上角我有一个 TextView,我需要在其中每 15 秒保持一次计数器以刷新 map 。布局很好。
我使用如下结构: HashMap > > OverallMap 如果我这样做: OverallMap . clear ( ) clear() 丢弃的所有内容(HashMap 对象、Integer 对
我在数据库中有 1000 张图像。在页面加载时,我随机显示 60 张图片,当用户滚动时,我通过 AJAX 请求添加 20 张图片。 第一种方法 我所做的是将所有图像加载到一个容器中,然后隐藏所有图像并
我正在使用 woocommerce 创建一个网上商店。 我想在每个产品上添加一个包含产品信息的表格,例如颜色、交货时间等等。 但是当我添加这张表时。本产品消失后的所有内容。 我的表的代码: td {
This question already has an answer here: What does an empty value for the CSS property content do?
因此,我正在与我的 friend 一起为 Google Chrome 开发一个扩展程序,对于大多数功能(即日历、设置等),我们打开一个模式,这样我们就不必重定向到另一个页面。当您在内容之外单击时,我们
我将可变高度的 CSS 框设置为在更大的 div 中向左浮动。现在我想添加一个标题,其中文本在框的左侧垂直显示(旋转 90 度),如下面的链接所示(抱歉还不能发布图片)。 http://imagesh
相关页面位于 www.codykrauskopf.com/circus 如果您查看我页面的右侧,在半透明容器和浏览器窗口边缘之间有一个间隙。我看了看,出于某种原因,wrap、main、content
我是一名优秀的程序员,十分优秀!