C# 将多个DataTable导出到Excel的一个Sheet中

最近接到一个需求,需要将多个DataTable导出到一个Excel的一个Sheet中,从上往下依次打印,表和表之间留一空行,还需要合并单元格和给表头填充颜色。

网上搜索一番之后,决定使用微软官方的OpenXml插件。

一、在NuGet中添加OpenXml

点击你的项目右键 -> “管理NuGet程序包”。

C# 将多个DataTable导出到Excel的一个Sheet中_第1张图片

然后点击作者为“Microsoft”的那个下载即可。

C# 将多个DataTable导出到Excel的一个Sheet中_第2张图片

二、代码示例

需求多,业务繁忙,来不及解释了,先贴上代码,后期有时间再深入研究一波。

/// 
/// 将多个datatable导入到一个excel的一个sheet中
/// 
/// 
/// 
public static void CreatMultiDataTablesToOneSheetData(string excelFilePath, DataTable[] tables, string sheetName, string tableNameRgb = "B0E0E6")
{
    // 创建文件
    SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(excelFilePath, SpreadsheetDocumentType.Workbook);
    WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
    workbookpart.Workbook = new Workbook();
    WorksheetPart worksheetPart = workbookpart.AddNewPart();
    SheetData sheetData = new SheetData();

    #region 添加样式
    var stylesPart = spreadsheetDocument.WorkbookPart.AddNewPart();
    stylesPart.Stylesheet = new Stylesheet();
    //定义字体集  (先定义字体集,然后再把字体加入到字体集中)
    stylesPart.Stylesheet.Fonts = new Fonts()
    {
        Count = (UInt32Value)3U // 表名,列名,内容
    };
    //定义字体
    Font tableTitleFont = new Font(
        new FontSize() { Val = 14D },
        new FontName() { Val = "Calibri" },
        new FontFamily() { Val = 2 },
        new FontScheme() { Val = FontSchemeValues.Major }
        );
    stylesPart.Stylesheet.Fonts.Append(tableTitleFont);
    Font columnFont = new Font(
        new FontSize() { Val = 12D },
        new FontName() { Val = "Calibri" },
        new FontFamily() { Val = 2 },
        new FontScheme() { Val = FontSchemeValues.Major }
        );
    stylesPart.Stylesheet.Fonts.Append(columnFont);
    Font contentFont = new Font(
        new FontSize() { Val = 11D },
        new FontName() { Val = "Calibri" },
        new FontFamily() { Val = 2 },
        new FontScheme() { Val = FontSchemeValues.Major }
        );
    stylesPart.Stylesheet.Fonts.Append(contentFont);
    // 边界
    stylesPart.Stylesheet.Borders = new Borders();
    stylesPart.Stylesheet.Borders.Count = 1;
    stylesPart.Stylesheet.Borders.AppendChild(new Border());
    // 填充
    stylesPart.Stylesheet.Fills = new Fills();
    var fillTableName = new PatternFill() { PatternType = PatternValues.Solid };
    fillTableName.ForegroundColor = new ForegroundColor { Rgb = HexBinaryValue.FromString(tableNameRgb) };
    var fillColumn = new PatternFill() { PatternType = PatternValues.Solid };
    fillColumn.ForegroundColor = new ForegroundColor { Rgb = HexBinaryValue.FromString(tableNameRgb) };
    var fillDefault = new PatternFill() { PatternType = PatternValues.Solid };
    fillDefault.ForegroundColor = new ForegroundColor { Rgb = HexBinaryValue.FromString(tableNameRgb) };
    stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = fillTableName });
    stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = fillColumn });
    stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = fillDefault });
    stylesPart.Stylesheet.Fills.Count = 3;
    stylesPart.Stylesheet.CellStyleFormats = new CellStyleFormats();
    stylesPart.Stylesheet.CellStyleFormats.Count = 1;
    stylesPart.Stylesheet.CellStyleFormats.AppendChild(new CellFormat());
    // 定义格式组合
    stylesPart.Stylesheet.CellFormats = new CellFormats();
    stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat());    // 必须要加这个,否则打不开
    stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat { FontId = 0, BorderId = 0, FillId = 2, ApplyFill = true }).AppendChild(new Alignment { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center });
    stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat { FontId = 1, BorderId = 0, FillId = 0, ApplyFill = true }).AppendChild(new Alignment { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center });
    stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat { FontId = 2, BorderId = 0, FillId = 0, ApplyFill = true }).AppendChild(new Alignment { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center });

    stylesPart.Stylesheet.CellFormats.Count = 4;   // 4种组合
    stylesPart.Stylesheet.Save();
    #endregion
    List mergePosList = new List();
    int rowIndex = 1;   // 计算标题在哪一行
    for (int i = 0; i < tables.Count(); i++)
    {
        mergePosList.Add(GetColumnName(0) + rowIndex + ":" + GetColumnName(tables[i].Columns.Count - 1) + rowIndex);
        // 创建表明行
        Row tableNameRow = new Row();
        for (int tr = 0; tr < tables[i].Columns.Count; tr++)
        {
            Cell dataCell = new Cell();
            dataCell.CellValue = (tr == 0 ? new CellValue(tables[i].TableName) : new CellValue(""));
            dataCell.DataType = CellValues.String;
            dataCell.StyleIndex = 1;
            tableNameRow.AppendChild(dataCell);
        }
        sheetData.AppendChild(tableNameRow);
        // 创建列名行
        Row headLineRow = new Row();
        for (int hr = 0; hr < tables[i].Columns.Count; hr++)
        {
            Cell dataCell = new Cell();
            dataCell.CellValue = new CellValue(tables[i].Columns[hr].ToString());
            dataCell.DataType = CellValues.String;
            dataCell.StyleIndex = 2;
            headLineRow.AppendChild(dataCell);
        }
        sheetData.AppendChild(headLineRow);
        // 创建表格内容行
        for (int r = 0; r < tables[i].Rows.Count; r++)
        {
            Row row = new Row();
            for (int c = 0; c < tables[i].Columns.Count; c++)
            {
                Cell dataCell = new Cell();
                dataCell.CellValue = new CellValue(tables[i].Rows[r][c].ToString());
                dataCell.DataType = CellValues.String;
                dataCell.StyleIndex = 3;
                row.AppendChild(dataCell);
            }
            sheetData.Append(row);
        }
        sheetData.Append(new Row());
        rowIndex += tables[i].Rows.Count + 3;   // 总数据行+表名行和列名行和一个空行
    }
    worksheetPart.Worksheet = new Worksheet(sheetData);
    // 合并单元格
    MergeCells mergeCells = new MergeCells();
    for (int i = 0; i < mergePosList.Count; i++)
    {
        mergeCells.Append(new MergeCell() { Reference = new StringValue(mergePosList[i]) });
    }
    worksheetPart.Worksheet.InsertAfter(mergeCells, worksheetPart.Worksheet.Elements().First());
    Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
    Sheet sheet = new Sheet()
    {
        Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
        SheetId = new UInt32Value((uint)(1)),
        Name = sheetName
    };
    sheets.Append(sheet);
    workbookpart.Workbook.Save();
    spreadsheetDocument.Close();
}
/// 
/// 获取excel对应的位置名
/// 
/// 从0开始
/// 
public static string GetColumnName(int index)
{
    string name = "";
    char[] columnNames = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    int num = index;
    do
    {
        int i = num % 26;
        name = columnNames[i] + name;
        num = num / 26 - 1;
    } while (num > -1);
    if (string.IsNullOrEmpty(name))
        name = "A";
    return name;
}

三、准备测试代码

准备两张数据表测试一下,代码如下:

DataTable dt1 = new DataTable("产品型号");
dt1.Columns.Add("Type");
dt1.Columns.Add("Size");
dt1.Rows.Add(new string[] { "SKI-1", "8mm" });
dt1.Rows.Add(new string[] { "SKI-1", "8mm" });
dt1.Rows.Add(new string[] { "SKI-1", "8mm" });
dt1.Rows.Add(new string[] { "SKI-2", "9mm" });
dt1.Rows.Add(new string[] { "SKI-3", "10mm" });
DataTable dt2 = new DataTable("角色信息");
dt2.Columns.Add("Name");
dt2.Columns.Add("Gender");
dt2.Columns.Add("Province");
dt2.Rows.Add(new string[] { "张三", "男", "广东省" });
dt2.Rows.Add(new string[] { "李四", "女", "湖南省" });
dt2.Rows.Add(new string[] { "黄二", "女", "福建省" });
dt2.Rows.Add(new string[] { "王五", "男", "广西省" });

四、测试结果

调用上面写的方法,即可导出excel。

CreatMultiDataTablesToOneSheetData(@"D:\导出Testl.xlsx", new DataTable[] { dt1,dt2 }, "导出测试");

结果如下图:

C# 将多个DataTable导出到Excel的一个Sheet中_第3张图片

原文首发于:https://hjxlog.com/posts/20200717a1.html

你可能感兴趣的:(C#)