NET - .NET Core WebAPI + Vue + Axios 导出Excel / CSV
程序员文章站
2024-01-21 14:44:52
...
这两种方法目前如果遇到0开头的数据,会默认把0去掉,可以考虑如果StartsWith(“0”),则在前面加个单引号(即’)
不推荐Excel导出,因为Excel2003一个Sheet最多导出65535条,Excel2007是10万4000多条,数据量大会报错,所以推荐使用CSV导出
- 导出 Excel
/// <summary>
/// 将 DataTable 转换为 Excel
/// 需在 nuget 安装 DotNetCore.NPOI
/// </summary>
/// <param name="table">数据表</param>
/// <param name="sheetName">sheet名称</param>
/// <returns></returns>
public static byte[] DataTableToExcel(DataTable table, string title = null, string sheetName = "Sheet")
{
try
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet(sheetName);
int cellsIndex = 0;
// 标题
if (!string.IsNullOrEmpty(title))
{
// 填充数据
IRow cellsTitle = sheet.CreateRow(0);
cellsTitle.CreateCell(0).SetCellValue(title);
// 合并单元格
sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 1, 0, table.Columns.Count - 1));
cellsIndex = 2;
}
// 填充表头
IRow cellsHeader = sheet.CreateRow(cellsIndex);
for (int i = 0; i < table.Columns.Count; i++)
{
cellsHeader.CreateCell(i).SetCellValue(table.Columns[i].ColumnName);
}
// 填充数据
cellsIndex += 1;
foreach (DataRow dr in table.Rows)
{
IRow row = sheet.CreateRow(cellsIndex);
for (int i = 0; i < table.Columns.Count; i++)
{
row.CreateCell(i).SetCellValue(StrHelper.ToString(dr[i]));
}
cellsIndex++;
}
byte[] buffer = null;
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
buffer = ms.GetBuffer();
ms.Close();
}
return buffer;
}
catch (Exception)
{
return null;
}
}
- 导出 CSV
/// <summary>
/// 将 DataTable 转换为 CSV
/// </summary>
/// <param name="table">数据表</param>
/// <returns></returns>
public static Stream DataTableToCsv(DataTable table)
{
try
{
StringBuilder builder = new StringBuilder();
DataColumn column;
int iColCount = table.Columns.Count;
// 处理表头
for (int i = 0; i < iColCount; i++)
{
if (i != 0) builder.Append(",");
builder.Append("\"" + table.Columns[i].ColumnName + "\"");
}
builder.AppendLine();
// 处理内容
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < iColCount; i++)
{
column = table.Columns[i];
if (i != 0) builder.Append(",");
if (Convert.IsDBNull(row[column])) builder.Append("\"\"");
//else if (row[column].ToString().StartsWith("0")) builder.Append("\"'" + row[column].ToString() + "\"");
else builder.Append("\"" + row[column].ToString() + "\"");
}
builder.AppendLine();
}
byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(builder.ToString());
Stream stream = new MemoryStream(bytes);
return stream ;
}
catch (Exception)
{
return null;
}
}
- .Net Core WebAPI Controller
/// <summary>
/// 导出 Excel
/// </summary>
/// <returns></returns>
[HttpGet("exportExcel")]
public async Task<IActionResult> ExportExcel()
{
DataTable dataTable = new DataTable(); // 此处准备 dataTable 数据
string name = "数据详情";
byte[] bytes = Utils.DataTableToExcel(dataTable, name, name);
return File(bytes, "application/octet-stream", $"{name}_{DateTime.Now:yyyyMMddHHmmssfff}.xlsx");
}
/// <summary>
/// 导出 CSV
/// </summary>
/// <returns></returns>
[HttpGet("exportCSV")]
public async Task<IActionResult> ExportCSV()
{
DataTable dataTable = new DataTable(); // 此处准备 dataTable 数据
System.IO.Stream stream = Utils.DataTableToCsv(dataTable);
return File(stream, "application/octet-stream", $"数据详情_{DateTime.Now:yyyyMMddHHmmssfff}.csv");
}
- .Net Core Startup.cs 配置
这里配置 .WithExposedHeaders("Content-Disposition")
是因为 Vue Axios response.headers 中默认获取不到 content-disposition 属性
public void ConfigureServices(IServiceCollection services)
{
// ......
// 处理 api 请求跨域
services.AddCors(options =>
{
options.AddPolicy("cors",
builder =>
{
builder.AllowAnyMethod()
.AllowAnyOrigin()
.AllowAnyHeader()
.WithExposedHeaders("Content-Disposition");
});
});
// ......
}
- Vue Axios
service.interceptors.response.use(
response => {
// blob 直接返回文件流数据
if (response.config.responseType === 'blob') {
console.log(response.headers);
const fileName = decodeURI(
// response.headers['content-disposition'] 默认获取不到,需要在 .Net Core Startup.cs 中进行配置
response.headers['content-disposition'].split('filename*=UTF-8\'\'')[1]
)
return Promise.resolve({ data: response.data, fileName: fileName })
}
// ......
},
error => {
return Promise.reject(error)
}
)
- Vue 请求接口
export function exportCSV(param) {
return request({
url: '/controller/exportCSV',
method: 'get',
params: { ...param },
responseType: 'blob'
})
}
- Vue 下载实现
export default {
data() {
return {
listQuery: {},
};
},
created() {},
methods: {
// 导出报表
onExport() {
exportCSV(this.listQuery).then((response) => {
let blob = new Blob([response.data], { type: response.data.type });
// 针对于 IE 浏览器的处理, 因部分 IE 浏览器不支持 createObjectURL
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, response.fileName);
} else {
var downloadElement = document.createElement("a");
var href = window.URL.createObjectURL(blob); // 创建下载的链接
downloadElement.href = href;
downloadElement.download = response.fileName; // 下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); // 点击下载
document.body.removeChild(downloadElement); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 释放掉 blob 对象
}
});
},
},
};
下一篇: 设计模式-1 简单工厂设计模式
推荐阅读
-
NET - .NET Core WebAPI + Vue + Axios 导出Excel / CSV
-
.Net Core导出Excel防止重提交
-
.net core webapi 导出excel
-
.Net core_Excel 导出二维码(以导出箱单为例)
-
.NET CORE webapi epplus 导入导出 (实习第一个月的笔记)
-
.Net core_Excel 导出二维码(以导出箱单为例)
-
建议收藏:.net core 使用EPPlus导入导出Excel详细案例,精心整理源码已更新至开源模板
-
net core WebApi——使用NPOI导入导出操作
-
Asp.Net Core实现Excel导出功能的实现方法
-
ASP.NET Core 导入导出Excel xlsx 文件实例