C# 使用EPPlus如何生成数字为数字而非文本的电子表格

C# 使用EPPlus如何生成数字为数字而非文本的电子表格,c#,excel,epplus,C#,Excel,Epplus,我正在使用LoadFromArrays从列表创建电子表格 数组的第一个条目是标题,其他条目可能是数字、文本或日期(但列表中的每个数组都相同) 生成的Excel工作表具有绿色三角形警告,表示数字格式为文本 我循环遍历所有单元格,并将其格式设置为数字,如sows.cells[I,j].Style.Numberformat.format=“0” 然而,问题仍然存在,我仍然看到绿色警告,即使当我查看格式单元格…对话框时,数字格式设置为数字 我的选择是什么?我可以知道更多关于每列中的类型的信息,但是如何设

我正在使用
LoadFromArrays
列表创建电子表格

数组的第一个条目是标题,其他条目可能是数字、文本或日期(但列表中的每个数组都相同)

生成的Excel工作表具有绿色三角形警告,表示数字格式为文本

我循环遍历所有单元格,并将其格式设置为数字,如so
ws.cells[I,j].Style.Numberformat.format=“0”

然而,问题仍然存在,我仍然看到绿色警告,即使当我查看
格式单元格…
对话框时,数字格式设置为数字

我的选择是什么?我可以知道更多关于每列中的类型的信息,但是如何设置列标题呢


有比ePlus更好的解决方案吗?或者在下载之前我可以对电子表格进行更多的后期处理?

因为您使用的是对象数组,所以它们可以包含数字和字符串,看起来像数字,您必须遍历每个对象并确定其类型:

[TestMethod]
public void Object_Type_Write_Test()
{
    //http://stackoverflow.com/questions/31537981/using-epplus-how-can-i-generate-a-spreadsheet-where-numbers-are-numbers-not-text
    var existingFile = new FileInfo(@"c:\temp\temp.xlsx");
    if (existingFile.Exists)
        existingFile.Delete();

    //Some data
    var list = new List<Object[]>
    {
        new object[]
        {
            "111.11",
            111.11,
            DateTime.Now
        }
    };

    using (var package = new ExcelPackage(existingFile))
    {
        var ws = package.Workbook.Worksheets.Add("Sheet1");
        ws.Cells[1, 1, 2, 2].Style.Numberformat.Format = "0";
        ws.Cells[1, 3, 2, 3].Style.Numberformat.Format = "[$-F400]h:mm:ss\\ AM/PM";

        //This will cause numbers in string to be stored as string in excel regardless of cell format
        ws.Cells["A1"].LoadFromArrays(list);

        //Have to go through the objects to deal with numbers as strings
        for (var i = 0; i < list.Count; i++)
        {
            for (var j = 0; j < list[i].Count(); j++)
            {

                if (list[i][j] is string)
                    ws.Cells[i + 2, j + 1].Value = Double.Parse((string) list[i][j]);
                else if (list[i][j] is double)
                    ws.Cells[i + 2, j + 1].Value = (double)list[i][j];
                else
                    ws.Cells[i + 2, j + 1].Value = list[i][j];

            }
        }

        package.Save();
    }
}
[TestMethod]
公共无效对象类型写入测试()
{
//http://stackoverflow.com/questions/31537981/using-epplus-how-can-i-generate-a-spreadsheet-where-numbers-are-numbers-not-text
var existingFile=new FileInfo(@“c:\temp\temp.xlsx”);
if(existingFile.Exists)
existingFile.Delete();
//一些数据
变量列表=新列表
{
新对象[]
{
"111.11",
111.11,
约会时间,现在
}
};
使用(var package=new ExcelPackage(existingFile))
{
var ws=package.Workbook.Worksheets.Add(“Sheet1”);
ws.Cells[1,1,2,2].Style.Numberformat.Format=“0”;
ws.Cells[1,3,2,3].Style.Numberformat.Format=“[$-F400]h:mm:ss\\AM/PM”;
//这将导致字符串中的数字在excel中存储为字符串,而不考虑单元格格式
ws.Cells[“A1”].loadFromArray(列表);
//必须遍历对象才能将数字作为字符串处理
对于(var i=0;i
通过上面的内容,您可以看到下图作为输出注释,左上角的单元格带有绿色箭头,因为它是由
LoadFromArray
编写的字符串,看起来像一个数字:


我基于EPPlus
LoadFromArray
创建了一个扩展方法
LoadFormulasFromArray
。该方法假定列表中的所有对象都将被视为公式(而不是
LoadFromArray
)。重要的是
Value
Formula
属性都采用
string
而不是特定类型。我认为这是一个错误,因为无法区分字符串是
文本
还是
公式
。实现
公式
类型将启用重载和类型检查,从而使总是做正确的事情成为可能

// usage: ws.Cells[2,2].LoadFormulasFromArrays(MyListOfObjectArrays)

public static class EppPlusExtensions
{
    public static ExcelRangeBase LoadFormulasFromArrays(this ExcelRange Cells, IEnumerable<object[]> Data)
    {
        //thanx to Abdullin for the code contribution
        ExcelWorksheet _worksheet = Cells.Worksheet;
        int _fromRow = Cells.Start.Row;
        int _fromCol = Cells.Start.Column;
        if (Data == null) throw new ArgumentNullException("data");

        int column = _fromCol, row = _fromRow;

        foreach (var rowData in Data)
        {
            column = _fromCol;
            foreach (var cellData in rowData)
            {
                Cells[row, column].Formula = cellData.ToString();
                column += 1;
            }
            row += 1;
        }
        return Cells[_fromRow, _fromCol, row - 1, column - 1];
    }
}
//用法:ws.Cells[2,2].LoadFormulasFromarray(MyListoFobjectArray)
公共静态类eppplus扩展
{
公共静态ExcelRangeBase LoadFormulasFromarray(此ExcelRange单元格,IEnumerable数据)
{
//thanx对Abdullin的代码贡献
Excel工作表_工作表=单元格。工作表;
int _fromRow=Cells.Start.Row;
int _fromCol=Cells.Start.Column;
如果(Data==null)抛出新的ArgumentNullException(“数据”);
int column=\u fromCol,row=\u fromrrow;
foreach(数据中的var rowData)
{
列=_fromCol;
foreach(rowData中的var cellData)
{
单元格[行,列].Formula=cellData.ToString();
列+=1;
}
行+=1;
}
返回单元格[_fromrrow,_fromCol,row-1,column-1];
}
}

诀窍是不要将数字作为“原始对象”传递给EPPlus,而是正确地转换它们

以下是我如何在使用EPPlus制作的DataTable to Excel导出方法中做到这一点的:

if (dc.DataType == typeof(int)) ws.SetValue(row, col, !r.IsNull(dc) ? (int)r[dc] : (int?)null);
else if (dc.DataType == typeof(decimal)) ws.SetValue(row, col, !r.IsNull(dc) ? (decimal)r[dc] : (decimal?)null);
else if (dc.DataType == typeof(double)) ws.SetValue(row, col, !r.IsNull(dc) ? (double)r[dc] : (double?)null);
else if (dc.DataType == typeof(float)) ws.SetValue(row, col, !r.IsNull(dc) ? (float)r[dc] : (float?)null);
else if (dc.DataType == typeof(string)) ws.SetValue(row, col, !r.IsNull(dc) ? (string)r[dc] : null);
else if (dc.DataType == typeof(DateTime))
{
    if (!r.IsNull(dc))
    {
        ws.SetValue(row, col, (DateTime)r[dc]);
        // Change the following line if you need a different DateTime format
        var dtFormat = "dd/MM/yyyy";
        ws.Cells[row, col].Style.Numberformat.Format = dtFormat;
    }
    else ws.SetValue(row, col, null);
}
重要:值得注意的是,
DateTime
值需要更多的工作才能正确处理,因为我们希望以某种方式对其进行格式化,并且可以说,支持列中的空值:上述方法满足了这两个要求


我在年发布了完整的代码示例(使用EPPlus将DataTable转换为Excel文件)。

通常,这些绿色三角形来自存储在字符串变量或属性中的数字(在代码中)。因此,无论您如何设置excel,都必须在代码中将字符串转换为数字。可能是这样吗?一次投票和一个小勾号都是对这个神奇的帮助的小小补偿。。。我真的被这一个弄得乱七八糟@鲁弗娜,没问题。很高兴这有帮助。