簡體   English   中英

使用EPPlus如何生成電子表格,其中數字是數字而不是文本

[英]Using EPPlus how can I generate a spreadsheet where numbers are numbers not text

我正在使用LoadFromArraysList<object[]>創建電子表格

數組的第一個條目是標題,其他條目可能是數字,文本或日期(但列表中的每個數組都相同)。

生成的Excel工作表具有綠色三角形警告,表示數字被格式化為文本。

我循環遍歷所有單元格並將其格式設置為數字,如此ws.Cells[i, j].Style.Numberformat.Format = "0";

然而問題仍然存在,我仍然看到綠色警告,即使我在查看Format Cell...對話框中將數字格式設置為數字。

我有什么選擇? 我可以更多地了解每列中的類型,但是如何設置列標題?

有比EPPlus更好的解決方案嗎? 或者在下載之前我可以做一些電子表格的后期處理?

由於您使用的是對象數組,因此它們可以包含看起來像數字的數字和字符串,您必須遍歷每個對象並確定其類型:

[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();
    }
}

使用上面的內容,您可以看到下面的圖像作為輸出注意左上角的單元格帶有綠色箭頭,因為它是一個由LoadFromArray編寫的字符串,看起來像一個數字:

Excel輸出

我創建了一個基於EPPlus LoadFromArray的擴展方法LoadFormulasFromArray 該方法假定列表中的所有對象都被視為公式(而不是LoadFromArray )。 大圖是ValueFormula屬性都采用string而不是特定的Type。 我認為這是一個錯誤,因為如果字符串是TextFormula則無法區分。 實現Formula類型將啟用重載和類型檢查,從而可以始終做正確的事情。

// 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];
    }
}

訣竅是不將數字作為“原始對象”傳遞給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值需要更多的工作才能正確處理,因為我們希望以某種方式對其進行格式化,並且可以說,支持列中的NULL值:上述方法滿足了這兩個要求。

在我的博客上發布這篇文章的完整代碼示例(帶有EPPlus的DataTable到Excel文件)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM