最近接到一个需求,需要将多个DataTable导出到一个Excel的一个Sheet中,从上往下依次打印,表和表之间留一空行,还需要合并单元格和给表头填充颜色。
网上搜索一番之后,决定使用微软官方的OpenXml插件。
点击你的项目右键 -> “管理NuGet程序包”。
然后点击作者为“Microsoft”的那个下载即可。
需求多,业务繁忙,来不及解释了,先贴上代码,后期有时间再深入研究一波。
///
/// 将多个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 }, "导出测试");
结果如下图:
原文首发于:https://hjxlog.com/posts/20200717a1.html