前端:
export function xxxx(query) {
return request({
url: 'xxxx/xxxxx',
method: 'get',
params: query,
responseType: 'blob' // 设置响应类型为二进制数据
})
}
xxxx() {
this.queryForm.wayExport = 0; //这里标记导出类型
xxx(this.queryForm)
.then((response) => {
const blob = new Blob([response]);
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "统计报表.xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.$message.success("导出成功!");
})
.catch((error) => {
console.error(error);
});
},
定义映射关系:
// 定义了一个映射字典,将表头名称映射到类的属性名
var headerPropertyMap = new Dictionary<string, string>
{
{ "姓名", "name" },
{ "年龄", "age" },
....
};
//转成List传入方法中
headerPropertyMap.Keys.ToList()
在appsettings里面添加许可证:
"EPPlus": {
//EPPlus配置 添加许可证。
"ExcelPackage": {
"LicenseContext": "Commercial"
}
},
后端工具类:
/// <summary>
/// 导出工具类
/// </summary>
public class ExcelExportHelper
{
/// <summary>
/// 导出查询数据,涉及到计算可先将结果封装到类中,再导出。
/// </summary>
/// <param name="data">导出数据</param>
/// <param name="worksheetName">工作区名称</param>
/// <param name="title">标题</param>
/// <param name="titleMergeRange">标题合并长度</param>
/// <param name="titleFontColor">标题颜色</param>
/// <param name="titleBackgroundColor">标题背景色</param>
/// <param name="headers">表头</param>
/// <param name="fontSize">字体大小</param>
/// <param name="summation">是否合计</param>
/// <param name="crossColumn">合计合并几列</param>
/// <param name="hashMap">合计数据哪些指定列,值</param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static FileResult ExportResults<T>(List<T> data, string worksheetName, string title,
string titleMergeRange, Color titleFontColor, Color titleBackgroundColor, List<string> headers,
int fontSize, bool summation, int crossColumn, Dictionary<int, int> hashMap, Dictionary<string, string> headerPropertyMap)
{
//示例 hashMap.Add(5, 10); 合计第5列字段,值为10
//(yourList.ToList(), "sheet", "导出名称", "A1:D1",
// Color.Black,
// Color.Aqua, new List<string> { "字段一", "字段二" ,...},14,false,2,);
using (var package = new ExcelPackage())
{
//添加工作表
var worksheet = package.Workbook.Worksheets.Add(worksheetName);
//起始行
var StartLine = 0;
//最后一行
var lastLine = 0;
// 添加标题
if (title != "")
{
var titleRange = worksheet.Cells[titleMergeRange];
titleRange.Merge = true;
titleRange.Value = title;
titleRange.Style.Font.Size = 16;
titleRange.Style.Font.Bold = true;
titleRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
titleRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
titleRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
titleRange.Style.Fill.BackgroundColor.SetColor(titleBackgroundColor);
titleRange.Style.Font.Color.SetColor(titleFontColor);
titleRange.Style.Border.BorderAround(ExcelBorderStyle.Thin, Color.Black);
StartLine = 2;
}
else
{
StartLine = 1;
}
// 添加表头
for (int i = 0; i < headers.Count; i++)
{
worksheet.Cells[StartLine, i + 1].Value = headers[i];
worksheet.Cells[StartLine, i + 1].Style.Font.Bold = true;
worksheet.Cells[StartLine, i + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
worksheet.Cells[StartLine, i + 1].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
worksheet.Cells[StartLine, i + 1].Style.Font.Size = fontSize;
worksheet.Column(i + 1).Width = 20; //设置列宽
}
StartLine++;
// var property = typeof(T).GetProperty("PropertyName"); // 替换 "PropertyName" 为要获取的属性名
// 根据映射填充数据
//导出的时间显示为数字(如45254.625)通常是因为Excel将日期和时间以序列数的形式存储,其中1代表1900年1月1日午夜,而小数部分代表一天中的时间。因此,45254.625代表的是1900年1月1日以来的第45254天加上大约0.625天,即15小时(0.625 * 24小时)。
// 预先找出所有包含"时间"或"日期"的列索引
var dateTimeHeadersIndexes = headers
.Select((header, index) => new { Header = header, Index = index })
.Where(x => x.Header.Contains("时间") || x.Header.Contains("日期"))
.Select(x => x.Index)
.ToList();
for (int i = 0; i < data.Count; i++)
{
var item = data[i];
for (int j = 0; j < headers.Count; j++)
{
if (headerPropertyMap.TryGetValue(headers[j], out var propertyName))
{
var property = typeof(T).GetProperty(propertyName);
if (property != null)
{
var value = property.GetValue(item);
worksheet.Cells[i + StartLine, j + 1].Value = value;
// 如果当前列索引在需要格式化的列索引列表中,并且值是DateTime类型,则设置格式
if (dateTimeHeadersIndexes.Contains(j) && value is DateTime dateTimeValue)
{
SetDateTimeFormat(worksheet.Cells[i + StartLine, j + 1], "yyyy-mm-dd hh:mm:ss");
}
}
}
}
lastLine = i + StartLine;
}
//是否开启最终合计
if (summation)
{
lastLine += 1;
// 在最后一行添加合计
worksheet.Cells[lastLine, 1].Value = "合计";
foreach (var i in hashMap)
{
worksheet.Cells[lastLine, i.Key].Value = i.Value; //合计数量
}
// 合并单元格
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Merge = true;
// 设置合并单元格的水平和垂直对齐方式为居中
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.HorizontalAlignment =
ExcelHorizontalAlignment.Center;
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.VerticalAlignment =
ExcelVerticalAlignment.Center;
// 设置字体颜色为红色
worksheet.Cells[lastLine, 1, lastLine, crossColumn + hashMap.Count].Style.Font.Color
.SetColor(Color.Red);
// 设置合并单元格的填充颜色和边框
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.Fill.BackgroundColor
.SetColor(Color.LightGray);
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.Border
.BorderAround(ExcelBorderStyle.Thin, Color.Black);
// 设置合计行的字体加粗
worksheet.Cells[lastLine, 1, lastLine, crossColumn].Style.Font.Bold = true;
}
// 保存Excel文件到内存流
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
memoryStream.Position = 0;
return new FileStreamResult(memoryStream,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
// 提取设置单元格日期时间格式的方法
private static void SetDateTimeFormat(ExcelRange cell, string format)
{
cell.Style.Numberformat.Format = format;
}
}