如何在使用EPPlus时设置列类型

时间:2012-03-25 10:53:03

标签: epplus

我正在使用EPPlus生成Excel个文件,在DAL中我正在填充DataTable,将数据填充到表中,并将表传递给表示层。从那里我使用LoadFromDataTable()方法生成Excel文件。

一切正常,但我想将列的类型之一设置为Date。我尝试将DataTable的列类型设置为Date,然后将DataTable传递给表示层,但它似乎EPPlus,忽略它,或者无法识别,因为当我打开生成的Excel文件时,单元格的类型为Number

如果我手动设置单元格格式并将类型设置为Date,则Excel会显示正确的日期。那我怎么能实现这个呢?

5 个答案:

答案 0 :(得分:76)

您确实需要DataTable列具有正确的类型,但您还需要修改列或单元格的Style.Numberformat.Format属性。

假设您有一个名为ExcelWorksheet的{​​{1}}:

ws

答案 1 :(得分:37)

根据此讨论(epplus.codeplex.com/discussions/349927),您还可以将列格式设置为日期。

worksheet_1.Cells[row, 3].Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern;

答案 2 :(得分:2)

如果您的列可能会移动(因为我们知道最终用户往往变幻无常)或者您的电子表格中只有很多日期列,那么编写一些更通用的内容会很有帮助。这就是我刚写的内容。 它在我的POCO中找到所有DateTime类型的位置,并创建一个列表,然后用它来设置列格式。记住数据表是零基础而Excel不是。

        ws.Cells.LoadFromDataTable(tbl, true);
        var dPos = new List<int>();
        for (var i = 0; i < tbl.Columns.Count; i++)
            if (tbl.Columns[i].DataType.Name.Equals("DateTime"))
                dPos.Add(i);
        foreach (var pos in dPos)
        {
            ws.Column(pos+1).Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM";
        }

如果您正在执行多个数据表,则可能需要将其重构为函数。

这是一个免费赠品......我不能赞成这个代码。它需要一个POCO列表并将其转换为数据表。在我的工具包中,它已经使我的生活变得更轻松了。享受。

        public DataTable ConvertToDataTable<T>(IList<T> data)
    {
        var properties =
           TypeDescriptor.GetProperties(typeof(T));
        var table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            var row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }

答案 3 :(得分:1)

要使用excel格式的构建,您需要将正确的字符串传递给

const fs = require('fs');
const http = require('http');

function promiseAdapt(func, ...args) {
    return new Promise((resolve, reject) => {
        func.apply(this, args.concat((err, res) => {
            if(err) {
                reject(err.toString());
                return;
            }

            resolve(res || undefined);
        }));
    });
}

const server = http.createServer((req, res) => {
    let data = undefined;

    promiseAdapt(fs.readFile, '/etc/motd', { 
        encoding: 'utf8' 
    }).then(d => {
        data = d;

        let str = `${req.method} ${req.url} (${req.headers['user-agent'] || '?'}) from ${req.connection.remoteAddress}` + "\n";

        return promiseAdapt(fs.writeFile, 'access.log', str, {
            encoding: 'utf8',
            flag: 'a',
            mode: '0755'
        });
    }).then(() => {
        res.writeHead(200);
        res.end(data);
     }).catch(e => {
        res.writeHead(500);
        res.end(e);
    });
}).listen(8000);

属性。

现在,稍后在执行期间,可能在序列化期间,EPPlus将尝试将此格式属性与工作簿中的当前样式字典进行匹配。它可能取决于精确的库版本,但例如对于EPPlust 4.1.0.0,短日期键是“mm-dd-yy”。

对于4.1.0.0,您可以找到所有硬编码的代码和密钥,以便在以下格式中构建:

  1. ExcelNumberFormatXml.cs,sheet.Cells[1, 1].Style.Numberformat.Format - 这里所有这些代码实际上都包含在工作簿中,都是硬编码的
  2. 使用调试器并检查internal static void AddBuildIn(XmlNamespaceManager NameSpaceManager, ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats)枚举(作为关键用途Workbook.Styles.NumberFormats
  3. 使用调试器并检查ExcelNumberFormatXml.Format(非公开会员)Workbook.Styles.NumberFormats.以获取确切的密钥。

答案 4 :(得分:0)

这是一个不错的C#扩展方法,可帮助从带有标头和正确日期格式的集合中加载:

(用列标题的Description属性装饰您的属性)

public static class EpPlusExtensions
{
    public static void Load<T>(this ExcelWorksheet worksheet, IEnumerable<T> collection)
    {
        worksheet.Cells["A1"].LoadFromCollection(collection, true);

        var properties = typeof(T).GetProperties();

        for (var i = 0; i < properties.Length; i++)
        {
            if (new []{typeof(DateTime), typeof(DateTime?)}.Contains(properties[i].PropertyType)) 
            {
                worksheet.Column(i + 1).Style.Numberformat.Format = "m/d/yyyy";
            }
        }
    } 
}