〇、前言

对于将数据以 Excel 表格文件输出,还是比较常用的,也存在诸多情况,比如列固定或不固定、数据类型为 List<T>或 Json 对象等。

本文通过包 OfficeOpenXml.Extension.AspNetCore 实现两个方法导出列数固定和不固定的数据。

注意:OfficeOpenXml.Extension.AspNetCore 是一个基于 OfficeOpenXml 拓展,它依赖于 EPPlus,用于根据模板输出 Excel。

包控制台安装:

NuGet> Install-Package OfficeOpenXml.Extension.AspNetCore -Version 1.0.0

一、根据已知类型对象 List 下载

本章节方法适用背景:

  数据列数固定,且可罗列。

对于对象 List<T> 的属性,一般不会命名为汉字,那么就需要将列名转换为汉字,以方便数据清晰显示。

如下为一个基于 WebAPI 项目的固定列数,动态行数的下载实例:

// 安装包:OfficeOpenXml.Extension.AspNetCore // 支持 Core 3.1 及以上,Standard 2.0 及以上
using OfficeOpenXml;
using OfficeOpenXml.Style;
using Microsoft.AspNetCore.Mvc; // File 支持 [HttpGet]
public FileContentResult DownloadInfo()
{
try
{
string sql_datalist = "";
var resultlist = dapperFactory.Query<ShujuMXModel>(sql_datalist).ToList();
string sFileName = $"{Guid.NewGuid()}.xlsx";
FileInfo fileinfo = new FileInfo(System.IO.Path.Combine("C:/Files", sFileName));
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(fileinfo))
{
// 添加 worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("明细表");
// 添加头
worksheet.Cells[1, 1].Value = "序号";
worksheet.Cells[1, 2].Value = "公司";
worksheet.Cells[1, 3].Value = "日期";
// 添加值
for (int i = 0; i < resultlist.Count; i++)
{
worksheet.Cells["A" + (i + 2)].Value = resultlist[i].xuhao;
worksheet.Cells["B" + (i + 2)].Value = resultlist[i].gongsimc;
worksheet.Cells["C" + (i + 2)].Value = resultlist[i].riqi.Substring(0,10);
}
worksheet.Column(1).Width = 10; // 设置列宽,从第 1 列开始
worksheet.Column(2).Width = 30;
worksheet.Column(3).Width = 15;
worksheet.Row(1).Style.Font.Bold = true; // 给第一行内容设置加粗
worksheet.Cells.Style.WrapText = true; // 自动换行
worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Top;
// 给有数据的区域添加边框
using (ExcelRange excelRange = worksheet.Cells[1, 1, resultlist.Count + 1, 3]) // [从第一行开始,从第一列开始,到第几行,到第几列]
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin; // 实线
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin;
r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black); // 黑色
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
worksheet.Row(1).Style.Font.Bold = true;
worksheet.Row(1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; // 第一行内容水平居中
package.Save();
}
using (FileStream fs= fileinfo.OpenRead())
{
BinaryReader br = new BinaryReader(fs);
br.BaseStream.Seek(0, SeekOrigin.Begin); // 将文件指针设置到文件开
byte[] fileBytes = br.ReadBytes((int)br.BaseStream.Length);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, sFileName); // 返回文件对象,前端可直接进行下载动作
}
}
catch (Exception ex)
{
return null;
}
}

二、动态列数据库下载

本章节方法适用背景:

  数据列数不固定,且可循环取出,表头和对应的数据顺序相同。

动态列就是,列总数不固定,程序根据传入的列数确定第一行表头。

下面是一个根据 json 字符串,以 Excel 文件形式保存数据的实例。其中包含 “tableheader”节点,来指定动态表头;“tablebody”代表全部数据列表。

// 安装包:OfficeOpenXml.Extension.AspNetCore // 支持 Core 3.1 及以上,Standard 2.0 及以上
// 由于 Excel 2003 版本 和 2007 之后版本文件结构的差异性,当前扩展无法同时兼容两种模式,仅支持 *.xlsx 文件
using OfficeOpenXml;
using OfficeOpenXml.Style; public void DownloadByJsonstr(string xiazaisj)
{
// string jsonstr = "{\"tableheader\":[{\"mingcheng\":\"列名一\",\"daima\":\"bumenx1\",\"shifoutz\":true},{\"mingcheng\":\"列名二\",\"daima\":\"bumenx2\",\"shifoutz\":true}],\"tablebody\":[{\"kemumc\":\"科目一\",\"bumenx1\":0.12,\"bumenx2\":6.0,\"heji\":6.12,\"erjimx\":[{\"kemumc\":\"科目一明细科目1\",\"bumenx1\":0.0,\"bumenx2\":9.82,\"heji\":9.82},{\"kemumc\":\"科目一明细科目2\",\"bumenx1\":0.12,\"bumenx2\":6.18,\"heji\":6.3}]}]}";
var baobiaosj_json = Json_Object.StrToJson(xiazaisj);
var tableheader = xiazaisj_json["tableheader"];
// 前两列表头固定
List<string> headersname = new List<string>(){ "科目", "合计" }; // 用于显示
List<string> headerscode = new List<string>(){ "kemumc", "heji" }; // 用于取值
// 从第三列开始,按默认顺序加入后续表头
foreach (var thj in tableheader)
{
headersname.Add(thj["mingcheng"].ToString());
headerscode.Add(thj["daima"].ToString());
}
string sFileName = $"{Guid.NewGuid()}.xlsx";
FileInfo fileinfo = new FileInfo(System.IO.Path.Combine("C:/Log", sFileName));
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
List<TableRowModel> tableRowModels = new List<TableRowModel>();
using (ExcelPackage package = new ExcelPackage(fileinfo))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("数据表");
EpplusHelper.AddHeader(worksheet, headersname.ToArray()); // 添加表头
var tablebody = xiazaisj_json["tablebody"];
TableRowModel tableRowModel = new TableRowModel();
Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
foreach (var tablebody_first in tablebody)
{
tableRowModel = new TableRowModel();
keyValuePairs = new Dictionary<string, string>();
tableRowModel.kemumc = tablebody_first["kemumc"].ToString(); // "kemumc": "成本"
tableRowModel.heji = tablebody_first["heji"].ToString();
for (int ii = 2; ii < headerscode.Count; ii++)
{
keyValuePairs.Add(headerscode[ii], tablebody_first[headerscode[ii]].ToString()); // "bumenx1": 0.0
}
tableRowModel.dict_lie = keyValuePairs;
tableRowModels.Add(tableRowModel);
if (tablebody_first["erjimx"] != null)
{
foreach(var tablebody_second in tablebody_first["erjimx"])
{
tableRowModel = new TableRowModel();
keyValuePairs = new Dictionary<string, string>();
tableRowModel.kemumc = tablebody_second["kemumc"].ToString(); // "kemumc": "成本"
tableRowModel.heji = tablebody_second["heji"].ToString();
for (int ii = 2; ii < headerscode.Count; ii++)
{
keyValuePairs.Add(headerscode[ii], tablebody_second[headerscode[ii]].ToString()); // "bumenx1": 0.0
}
tableRowModel.dict_lie = keyValuePairs;
tableRowModels.Add(tableRowModel);
}
}
}
if (tableRowModels.Count > 0)
{
//添加动态数据
EpplusHelper.AddObjects(worksheet, 2, tableRowModels, headerscode);
}
worksheet.Column(1).Width = 20; // 设置列宽
worksheet.Column(2).Width = 20;
for (int ii = 3; ii <= headerscode.Count; ii++) // 为动态列设置统一列宽
{
worksheet.Column(ii).Width = 16;
}
//worksheet.Cells.Style.WrapText = true; // 自动换行
worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Top;
using (ExcelRange r = worksheet.Cells[1, 1, tableRowModels.Count + 1, headersname.Count])
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin;
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin; r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
worksheet.View.FreezePanes(2, 3); // 冻结第一行,以及前两列
worksheet.Row(1).Style.Font.Bold = true; // 第一行加粗
worksheet.Row(1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;// 第一行水平居中
package.Save();
}
}

EpplusHelper.cs 类,用作循环添加表头和数据。

using System;
using System.Collections.Generic;
using OfficeOpenXml; public static class EpplusHelper
{
/// <summary>
/// 通过 名称数组 添加表头
/// </summary>
/// <param name="sheet"></param>
/// <param name="headertexts"></param>
public static void AddHeader(ExcelWorksheet sheet, params string[] headertexts)
{
for (var i = 0; i < headertexts.Length; i++)
{
AddHeader(sheet, i + 1, headertexts[i]);
}
}
/// <summary>
/// 添加动态数据
/// </summary>
/// <param name="worksheet"></param>
/// <param name="startrowindex">从第几行开始</param>
/// <param name="items">行数据列表</param>
/// <param name="headerscode">列名代码列表,用于取数据</param>
public static void AddObjects(ExcelWorksheet worksheet, int startrowindex, IList<TableRowModel> items, List<string> headerscode)
{
for (var i = 0; i < items.Count; i++)
{
worksheet.Cells[i + startrowindex, 1].Value = items[i].kemumc; // 注意此处为兼容前两列固定列
worksheet.Cells[i + startrowindex, 2].Value = items[i].heji;
for (var j = 2; j < headerscode.Count; j++) // headercode:kemumc,heji,bumenx1,bumenx2...
{
worksheet.Cells
[i + startrowindex,
j + 1]
.Value
= items[i].dict_lie[headerscode[j]];
}
}
}
}

代码参考:C# 使用Epplus导出Excel [2]:导出动态列数据

.Net Core 如何数据导出 Excel?(EPPlus->OfficeOpenXml 实现固定列和动态列导出)的更多相关文章

  1. PHP导出excel文件,第一步先实现PHP模板导出不带数据

    今天继续研究PHP导出excel文件,把复杂的事情简单化,一步步实现功能,首先实现模板文件的导出,随后再实现写入数据后导出,最终实现功能,这是基本思路.中间可以加一步,先自己写入数据导出试试,随后再数 ...

  2. (ssh整合web导出excel)在ssh框架中使用poi正确导出具有比较高级固定格式的excel 整体过程,查询导出前后台下载

    (一) 接需求  :   需求相关   (贴图 ) 生成三核对文件 1.新增三核对菜单页面中,增加生成三核对文件功能按钮,弹窗可根据变电站.电压等级查询定值单. 2.定值单信息以表格形式展示,根据选择 ...

  3. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续2篇-模板导出综合示例)

    自ExcelUtility类推出以来,经过项目中的实际使用与不断完善,现在又做了许多的优化并增加了许多的功能,本篇不再讲述原理,直接贴出示例代码以及相关的模板.结果图,以便大家快速掌握,另外这些示例说 ...

  4. .net core 导出Excel(epplus 创建excel )

    [Route("getopenfrequencyexcel")] [HttpGet] public IActionResult GetOpenFrequencyExcel(int ...

  5. asp.net导出EXCEL的好方法!(好用,导出全部数据)

    1.调用方法: ExportExcel("application/ms-excel", "EXCEL名称.xls", GridView1, this.Page) ...

  6. java导出excel 浏览器直接下载或者或以文件形式导出

    /** * excel表格直接下载 */ public static void exportExcelByDownload(HSSFWorkbook wb,HttpServletResponse ht ...

  7. ASP.NET Core使用EPPlus导入导出Excel

    开发过程中,经常会遇到导入导出数据的需求,本篇博客介绍在.NET Core中如何使用EPPlus组件导入导出Excel EPPlus: EPPlus是使用Open Office XML格式(xlsx) ...

  8. 生成统计数据并导出Excel

    需求:看如下表格的统计需求 生产调度中心部门需要从IT技术部门得到这些统计数据 步骤: (1)获取所有的子公司列表 (2)遍历所有的子公司,获取每个子公司的库存信息 (3)遍历所有的库存信息,并对库存 ...

  9. PHP导出MySQL数据到Excel文件

    PHP导出MySQL数据到Excel文件 转载 常会碰到需要从数据库中导出数据到Excel文件,用一些开源的类库,比如PHPExcel,确实比较容易实现,但对大量数据的支持很不好,很容易到达PHP内存 ...

  10. 项目笔记:导出Excel功能分sheet页插入数据

    导出Excel功能分sheet页处理数据: /*导出EXCEL*/ public void createExcel() { log.info("导出Excel功能已经启动-BEGIN&quo ...

随机推荐

  1. Springboot整合Jwt实现用户认证

    前言 相信大家在进行用户认证中或多或少都要对用户进行认证,当前进行认证的方式有基于session.token等主流方式,但是目前使用最广泛的还是基于JWT的用户认证,特别适用于前后端分离的项目. 本篇 ...

  2. Golang 常用库之jwt-go

    本文地址 https://www.cnblogs.com/zichliang/p/17303759.html github地址:https://github.com/dgrijalva/jwt-go ...

  3. day103:MoFang:用户登录部分:客户端提交登录信息&APICloud集成防水墙验证码&保存用户登录状态

    目录 bug:修复jsonrpc修改源码以后celery无法运行的问题 1.客户端提交登录信息 2.在APICloud中集成防水墙验证码 3.保存用户登录状态 bug:修复jsonrpc修改源码以后c ...

  4. 【LeetCode】3.19 对称二叉树

    101. 对称二叉树 ​ 给你一个二叉树的根节点 root , 检查它是否轴对称. 示例 1: 输入:root = [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root = [1 ...

  5. Ununtu服务器安装Nginx与PHP

    Ununtu服务器安装Nginx与PHP 1. 安装Nginx: 1.1 sudo apt update sudo apt install nginx 验证结果,使用命令: sudo systemct ...

  6. 2023高效的mysql 随机语句 200万数据为例 用了 0.0030秒

    是的,如果数据表中有200万条记录,使用 ORDER BY RAND() 这种方式来随机选择记录会非常慢,因为 MySQL 需要对整个表进行排序,然后再返回指定数量的记录.这个过程需要消耗大量的时间和 ...

  7. ditto 添加统计粘贴次数功能

    通过观察ditto的表发现, 可以添加触发器进行统计粘贴次数的功能,不需要用源码 Ditto 是一款强大的 Windows 剪贴板增强工具,它支持64位操作系统,而且完全免费,绿色开源,支持中文,而且 ...

  8. S3 对象重命名

    本文所述操作适用于兼容 S3 协议的所有存储框架,包括 AWS S3.Aliyun OSS.MinIO.Ceph 等. 不知为何,截止目前,S3 协议并不包含对象重命名的接口.如果有重命名对象的需求, ...

  9. MAPPO学习笔记(1):从PPO算法开始

    由于这段时间的学习内容涉及到MAPPO算法,并且我对MAPPO算法这种多智能体算法的信息交互机制不甚了解,于是写了这个系列的笔记,目的是巩固知识,并且进行一些粗浅又滑稽的总结. 1.PPO算法的介绍 ...

  10. Consistency Models终结扩散模型

    最近看到一篇论文,觉得特别有意思,并且在学术界引起了不小的动静,他就是一致性模型,据说图像生成效果快.质量高,并且还可以实现零样本图像编辑,即不进行一些视觉任务训练,可以实现图像超分.修复.上色等功能 ...