我正在尝试从多个文件中读取一些值,并将它们保存在具有不同分组的新.xlsx文件中。我设计了一个非常简单的设置来测试具有空值的不同格式和行为。我总是在Excel中打开刚刚创建的文件以查看结果。到目前为止没问题。
但是在我的测试用例中,我可以实现以下两种方法之一:A)保存测试值(字符串)或B)强制Excel将它们视为具有给定格式(好)的数字,但丢失小数分隔符(非常糟糕) & strange)。
我已将问题追溯到下面代码段中的最后一行。自我分配的想法来自SO的某处,但现在我无法找到它。
如果该行被注释掉,则结果与string[,] contents
中的结果相同,只是它们被格式化为文本(并且Excel以“格式化为文本的数字”消息抱怨此行)。如果我取消注释,数字将被视为数字但会丢失小数分隔符。此问题可能是我在捷克共和国的事实,小数点分隔符是,
,这可能会给Excel带来麻烦。此外,读取从开始到double[,] contents
的值是不对的,因为我需要指示值是否不存在(空单元格)。而double?[,] contents
崩溃了Excel ......
excelApp = new Excel.Application();
excelWorkBooks = excelApp.Workbooks;
excelWorkBook = excelWorkBooks.Add();
excelSheets = excelWorkBook.Sheets;
excelWorkSheet = excelSheets[1]; //Beware! Excel is one-based as opposed to a zero-based C#
string[,] contents = new string[,] { { "1,23", "2,123123123", "3,1415926535" }, { "2,15", null, "" } };
int contentsHeight = contents.GetLength(0);
int contentsWidth = contents.GetLength(1);
System.Globalization.CultureInfo currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
string numberFormat = string.Format("0" + currentCulture.NumberFormat.NumberDecimalSeparator + "00E+00");
for (int column = 0; column < contentsWidth; column++) {
excelWorkSheet.Columns[column + 1].NumberFormat = numberFormat;
}
Excel.Range range = excelWorkSheet.Range[excelWorkSheet.Cells[1, 1], excelWorkSheet.Cells[contentsHeight, contentsWidth]];
range.Value = contents;
// range.Value = range.Value; //Problematic place
编辑:为了测试,我尝试将NumberFormat从0,00E+00
更改为0,0
,0.0
,#,#
,但没有成功。崩溃(小数点)或保留为文本。
答案 0 :(得分:0)
在将数字写入单元格之前,无需将数字转换为文本。 Excel理解数字。另一个问题是代码试图将数组设置为整个范围的值,就像粘贴到Excel中一样。
可以直接使用简单的循环设置数字,甚至是空值,例如
double?[,] contents = new double?[,] { { 1.23, 2.123123123, 3.1415926535 },
{ 2.15, null, null } };
int contentsHeight = contents.GetLength(0);
int contentsWidth = contents.GetLength(1);
...
for(int i=0;i<= contentsHeight; i++)
for (int j = 0; j <= contentsWidth; j++)
excelWorkSheet.Cells[i+1,j+1].Value = contents[i,j];
不是通过Interop使用Excel,而是使用像EPPlus这样的包来直接生成xlsx
文件而不安装Excel。这样即使在无法安装Excel的Web服务器上也可以生成真实的Excel文件。
此特定问题的代码类似:
var file = new FileInfo("test.xlsx");
using (var pck = new ExcelPackage(file))
{
var ws = pck.Workbook.Worksheets.Add("Rules");
for(int i=0;i<= contentsHeight; i++)
for (int j = 0; j <= contentsWidth; j++)
ws.Cells[i+1,j+1].Value = contents[i,j];
pck.Save();
}
EPPlus有一些方便的方法可以轻松加载工作表,例如LoadFromDataTable或LoadFromCollection。如果数据来自DataTable,则创建工作表将非常简单:
var file = new FileInfo("test.xlsx");
using (var pck = new ExcelPackage(file))
{
var ws = pck.Workbook.Worksheets.Add("Rules");
ws.LoadFromDataTable(myTable);
pck.Save();
}
LoadFromDataTable返回ExcelRange
,它允许单元格格式化,就像Excel Interop一样。