- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
特别注意:本文设计的包(OfficeOpenXml.Extension.AspNetCore)依赖于 EPPlus 5.0.3 等更高版本,属于限制商业用途版本,因此只能用作个人或公司小范围内部使用.
对于将数据以 Excel 表格文件输出,还是比较常用的,也存在诸多情况,比如列固定或不固定、数据类型为 List<T>或 Json 对象等.
本文通过包 OfficeOpenXml.Extension.AspNetCore 实现两个方法导出列数固定和不固定的数据.
注意:OfficeOpenXml.Extension.AspNetCore 是一个基于 OfficeOpenXml 拓展,它依赖于 EPPlus,用于根据模板输出 Excel.
包控制台安装:
NuGet> Install-Package OfficeOpenXml.Extension.AspNetCore -Version 1.0.0
本章节方法适用背景:
数据列数固定,且可罗列.
对于对象 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]:导出动态列数据 。
最后此篇关于.NetCore如何数据导出Excel?(EPPlus->OfficeOpenXml实现固定列和动态列导出)的文章就讲到这里了,如果你想了解更多关于.NetCore如何数据导出Excel?(EPPlus->OfficeOpenXml实现固定列和动态列导出)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在 JavaScript 中,我们可以动态创建 元素并附加到 部分,以便为大量元素应用 CSS 规则。 这种方法的优点或缺点是什么? 如果它确实提供了与元素上的 javascript 迭代相比的性
我有这个代码 import "./HTTPMethod.dart"; import '../../DataModel/DataModel.dart'; mixin RouterMixin { HT
哪些 OLAP 工具支持动态、动态地创建维度或层次结构? 例如,层次结构将成员定义为:“前 5 名”、“前 6-10 名”、“其他”... 计算成员是通常的答案,我正在寻找不同的东西。计算器的问题。成
我正在 CakePHP 中创建一个“表单编辑器”。 该界面允许用户选择要应用于字段的验证,例如数字、电子邮件等 因此,我需要根据用户输入为模型动态创建验证。为此,我可以使用验证对象:https://b
这是一个场景: 我有一个Web服务,我们将其称为部署在tomcat(轴)上的StockQuoteService。通过此 Web 服务公开了 getStockQuote() 方法。 现在,我想构建一个
我正在尝试从服务器获取 JSON 响应并将其输出到控制台。 Future login() async { var response = await http.get( Uri.
我从另一个问题中得到了这段代码(感谢 chunhunghan)。我需要创建一个登录屏幕,并尝试根据服务器发回给我的响应来验证用户凭据,但是每次我尝试运行代码时,它都会给我“未处理的异常:Interna
当我在“Dart”主程序中运行它时,一切正常,并且我得到了一个与会者列表。但是,当我在我的 Flutter 应用程序中调用它时,出现错误: flutter:“List”类型不是“List>”类型的子类
本文实例为大家分享了js实现验证码动态干扰的具体代码,供大家参考,具体内容如下 效果一 效果二 代码一 ?
目前我正在为我的网站使用 No-Ip,我想使用 cloudflare 来抵御 ddos 和机器人程序。我注意到您需要一个用于 cloudflare 的域。我还搜索了网络,发现了一个叫做 cloud
有没有办法在 Excel VBA 中构建动态 if 语句?基本上我正在尝试创建一个参数化计算,用户将能够输入不同的变量,即 变量 1 “变量 2” “变量 3” 在这种情况下 变量 1 是单元格引用
大家好, 请查看上面的图片,我有两张 table 。在下面代码的第一个表中,我得到了这种格式。 但我想像 Table2 那样格式化,每个合并单元格中的行数是动态的,而且不一样。 有没有办法像table
如何根据我添加的 View 修改标题部分的高度?heightForHeaderInSection在 viewForHeaderInSection 之前被调用我不知道 View 大小,直到我创建它。 最
是否存在在运行时生成 AST/解析树的解析器?有点像一个库,它会接受一串 EBNF 语法或类似的东西并吐出数据结构? 我知道 antlr、jlex 和他们的同类。他们生成可以做到这一点的源代码。 (喜
我在持有汽车制造商的表格上有一个 MultipleChoiceField。我想将我的汽车数据库过滤到已检查的品牌,但这会导致问题。如何动态获取所有 Q(make=...) 语句? 我如何开始:['va
$end = preg_replace($pattern, $replacement, $str); 如何使替换字符串 $replacement 随 $str 中的每次匹配而变化?例如,我想用关联的图
我正在编写一个 VBA 程序,用于过滤表中的值。我试图使其成为一个适用于您提供的所有表格的通用程序。在我的程序中,我必须设置它正在过滤的表的范围:Set rng = dataSheet.Range("
我正在循环一个元素数组,并且我想使用给定的模板递归地显示该元素 然后在该模板内使用带有切换功能的按钮来显示/隐藏给定元素的Child的更深级别模板(Child也是一个元素) 这是我的模板
从客户端(html)发送表单,服务器端通过选择选项之一决定运行哪个函数。 const decideWho = (form) => { const choice = form.choice; c
我有一个具有以下属性的按钮: circle_normal.xml(在 res/drawable 中) circle.xml(在 res/drawable 中)
我是一名优秀的程序员,十分优秀!