〇、前言

对于将数据以 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. c#快速入门~在java基础上,知道C#和JAVA 的不同即可

    观看下文前提:如果你的主语言是java,现在想再学一门新语言C#,下文是在java基础上,对比和java的不同,快速上手C# C# 学习参考文档和开发工具 微软c#官方文档:https://learn ...

  2. day120:MoFang:修复宠物喂食饱食度不增加的BUG&修复宠物死亡导致数据错乱的BUG

    目录 BUG1:修复宠物喂食饱食度未增加的BUG BUG2:修复当用户拥有2个宠物时,如果第1个宠物挂了,会出现第二个宠物变成第1个宠物的情况,会导致数据发生混乱出现bug BUG1:修复宠物喂食饱食 ...

  3. 部署:戴尔iDRAC+Ubuntu 18.04系统安装

    Ubuntu镜像下载链接:http://mirrors.aliyun.com/ubuntu-releases/18.04/ 1.登录戴尔管理口 2.点击虚拟控制台 3.选择镜像 4.挂载镜像 5.选择 ...

  4. 【Git GitHub Idea集成】

    1 Git介绍 分布式版本控制工具 VS 集中式版本控制工具 git是一个免费开源的分布式版本控制系统,可以快速高效地处理从小型到中型的各种项目. 1.1 Git进行版本控制 集中式版本控制工具:如C ...

  5. cocos2d-x返回Android游戏黑屏解决办法

    返回Android游戏黑屏解决办法这几天逛cocos2d-x.org论坛,发现cocos2d-x的作者放出来一个帖子,用来解决返回Android游戏加载资源时黑屏的问题.帖子过些日子估计就沉了,所以转 ...

  6. Java 网络编程 —— Socket 详解

    构造 Socket 在[客户端/服务端]的通信模式中,客户端需要主动构造与服务器连接的 Socket,构造方法有以下几种重载形式: Socket() Socket(InetAddress addres ...

  7. 当我再次用Kotlin完成五年前已经通过Kotlin完成的项目后

      > 近日来对Kotlin的使用频率越来越高, 也对自己近年来写过的Kotlin代码尝试进行一个简单的整理. 翻到了自己五年前第一次使用Kotlin来完成的一个项目([贝塞尔曲线](https ...

  8. 当Serverless遇到Regionless:现状与挑战

    摘要:本文尝试基于分析现有的学术文章,剖析Serverless与Regionless并存时,在性能提升和成本控制两个方向的现状与挑战 本文分享自华为云社区<当Serverless遇到Region ...

  9. Python获取jsonp数据

    使用python爬取数据时,有时候会遇到jsonp的数据格式,由于不是json的,所以不能直接使用json.loads()方法来解析,需要先将其转换为json格式,再进行解析.在前面讲了jsonp的原 ...

  10. selenium配置远程测试环境

    开头 因为测试的时候需要不断打开浏览器,这样效率感觉不高,于是想着能不能开启一个浏览器,然后通过代码直接链接来调试就好了. 前提 要先安装好selenium 和 会查看配置自己的google版本和路径 ...