You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何导出保留原格式的DataTable至Excel、PDF?含样式、背景色

刚好之前帮同事解决过一模一样的需求!要导出DataTable还完整保留原格式(行背景色、列背景色、重复行的黄色高亮),核心是得先把DataTable的样式元数据存下来——毕竟默认的导出工具只会导数据,不会自动识别样式。下面分Excel和PDF两种场景给你具体实现方案:

导出到Excel(保留所有格式)

我常用EPPlus这个库(支持.NET Framework和.NET Core),它能完美还原单元格/行/列的样式。步骤分两步:

1. 先准备样式元数据

DataTable本身不直接存储样式信息,所以你需要提前把这些信息存起来:

  • 用字典记录哪些行对应什么背景色
  • 用HashSet标记重复行的索引(你需要先写逻辑判断哪些行是重复的,比如根据特定列的组合值)
  • 同理记录列的背景色(如果有的话)

示例代码(假设已经完成重复行判断):

// 行颜色映射:键=行索引,值=背景色
Dictionary<int, Color> rowBackgroundColorMap = new Dictionary<int, Color>();
// 重复行索引集合
HashSet<int> duplicateRowIndexes = new HashSet<int>();
// 列颜色映射:键=列索引,值=背景色
Dictionary<int, Color> columnBackgroundColorMap = new Dictionary<int, Color>();

// 这里假设你已经通过业务逻辑填充了上面的映射集合

2. 用EPPlus导出并应用样式

using OfficeOpenXml;
using System.Drawing;
using System.IO;

// 注意:EPPlus 5+需要设置LicenseContext
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

// 你的DataTable
DataTable dt = GetYourDataTable();

using (var excelPackage = new ExcelPackage())
{
    // 创建工作表
    var worksheet = excelPackage.Workbook.Worksheets.Add("导出数据");

    // 1. 写入表头并应用列样式
    for (int colIndex = 0; colIndex < dt.Columns.Count; colIndex++)
    {
        var cell = worksheet.Cells[1, colIndex + 1];
        cell.Value = dt.Columns[colIndex].ColumnName;

        // 应用列背景色
        if (columnBackgroundColorMap.ContainsKey(colIndex))
        {
            cell.Style.Fill.PatternType = ExcelFillStyle.Solid;
            cell.Style.Fill.BackgroundColor.SetColor(columnBackgroundColorMap[colIndex]);
        }
    }

    // 2. 写入数据行并应用行样式/重复行高亮
    for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++)
    {
        // 写入当前行的所有单元格数据
        for (int colIndex = 0; colIndex < dt.Columns.Count; colIndex++)
        {
            worksheet.Cells[rowIndex + 2, colIndex + 1].Value = dt.Rows[rowIndex][colIndex];
        }

        // 获取当前行的所有单元格区域
        var rowRange = worksheet.Cells[rowIndex + 2, 1, rowIndex + 2, dt.Columns.Count];

        // 优先应用重复行的黄色高亮(如果是重复行)
        if (duplicateRowIndexes.Contains(rowIndex))
        {
            rowRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
            rowRange.Style.Fill.BackgroundColor.SetColor(Color.Yellow);
        }
        // 否则应用行背景色
        else if (rowBackgroundColorMap.ContainsKey(rowIndex))
        {
            rowRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
            rowRange.Style.Fill.BackgroundColor.SetColor(rowBackgroundColorMap[rowIndex]);
        }
    }

    // 保存到文件(ASP.NET环境可以直接输出到Response)
    File.WriteAllBytes("导出数据.xlsx", excelPackage.GetAsByteArray());
}
导出到PDF(保留所有格式)

PDF导出我用iText7(现在的新版本,比旧版iTextSharp更稳定),核心思路和Excel一样:先准备样式元数据,再逐行逐单元格应用样式。

1. 同样先准备样式元数据

和Excel部分的rowBackgroundColorMap、duplicateRowIndexes、columnBackgroundColorMap完全一致,不用重复写。

2. 用iText7导出并应用样式

using iText.Kernel.Colors;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System.IO;

// 你的DataTable
DataTable dt = GetYourDataTable();

using (var fs = new FileStream("导出数据.pdf", FileMode.Create))
{
    // 创建PDF文档
    var pdfDocument = new PdfDocument(new PdfWriter(fs));
    var document = new Document(pdfDocument);

    // 创建PDF表格,列数和DataTable一致
    var pdfTable = new Table(dt.Columns.Count);
    pdfTable.SetWidthPercent(100);

    // 1. 添加表头并应用列样式
    foreach (DataColumn col in dt.Columns)
    {
        var cell = new Cell().Add(new Paragraph(col.ColumnName));
        
        // 应用列背景色
        if (columnBackgroundColorMap.ContainsKey(col.Ordinal))
        {
            var color = columnBackgroundColorMap[col.Ordinal];
            cell.SetBackgroundColor(new DeviceRgb(color.R, color.G, color.B));
        }
        
        pdfTable.AddCell(cell);
    }

    // 2. 添加数据行并应用行样式/重复行高亮
    for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++)
    {
        // 先添加当前行的所有单元格数据
        foreach (var cellValue in dt.Rows[rowIndex].ItemArray)
        {
            pdfTable.AddCell(new Cell().Add(new Paragraph(cellValue?.ToString() ?? string.Empty)));
        }

        // 获取当前行的所有单元格,统一设置样式
        var rowCells = pdfTable.GetRow(rowIndex + 1).GetCells(); // 表头是第0行,数据行从第1行开始
        Color targetColor = Color.WHITE;

        // 优先设置重复行的黄色高亮
        if (duplicateRowIndexes.Contains(rowIndex))
        {
            targetColor = Color.YELLOW;
        }
        // 否则设置行背景色
        else if (rowBackgroundColorMap.ContainsKey(rowIndex))
        {
            var dtColor = rowBackgroundColorMap[rowIndex];
            targetColor = new DeviceRgb(dtColor.R, dtColor.G, dtColor.B);
        }

        // 给当前行所有单元格应用背景色
        foreach (var cell in rowCells)
        {
            cell.SetBackgroundColor(targetColor);
        }
    }

    // 将表格加入文档并关闭
    document.Add(pdfTable);
    document.Close();
}
关键注意事项
  • 样式元数据的来源:如果你的DataTable是从WinForms/WPF的DataGridView绑定来的,那可以直接从控件的RowDefaultCellStyle、Rows[i].DefaultCellStyle里读取颜色,不用手动维护映射集合。
  • 重复行判断逻辑:你需要自己实现重复行的识别,比如遍历DataTable,用字典记录每个行的唯一标识(比如多列拼接的字符串),出现次数大于1的就是重复行,把对应的索引加入duplicateRowIndexes。
  • 库的版本和授权:EPPlus 5+需要设置非商业授权(如果是商业用途要购买授权);iText7也有商业授权要求,个人/非商业使用没问题。

内容的提问来源于stack exchange,提问作者Ganesh Malode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:54:44