С помощью EPPlus как я могу создать таблицу, где числа-это числа, а не текст

Я создаю таблицу с List<object[]> используя LoadFromArrays

первая запись массива является заголовком, другие записи, возможно, числа, текст или даты (но то же самое для каждого массива в списке).

созданный лист Excel имеет зеленый треугольник предупреждение о том, что число отформатировано как текст.

Я перебираю все ячейки и устанавливаю их формат в число так ws.Cells[i, j].Style.Numberformat.Format = "0";

однако проблема остается и я все еще вижу зеленое предупреждение, даже если формат номера установлен на номер, когда я смотрю в Format Cell... диалог.

Каковы мои варианты здесь? Я могу узнать немного больше о том, какой тип находится в каждом столбце, но как мне установить заголовок столбца?

есть ли лучшее решение, чем EPPlus? или еще одна обработка электронной таблицы, которую я могу сделать перед загрузкой?

2 ответов


поскольку вы используете массивы объектов, они могут содержать числа и строки, которые выглядят как числа, вам придется пройти через каждый объект и определить его тип:

[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 Output


я создал метод расширения LoadFormulasFromArray на основе EPPlus LoadFromArray. Метод предполагает, что все объекты в списке должны рассматриваться как формулы (в отличие от LoadFromArray). Общая картина такова, что оба Value и Formula свойства take string вместо определенного типа. Я вижу это как ошибку, потому что нет способа отличить, если строка Text или Formula. Реализации 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];
    }
}