二十七、OpenXml/Excel 操作
在企业管理系统中,系统对接Office功能是非常常见的需求。
什么是OpenXml
[来自百度百科] Open XML 的标准化工作是由 Ecma International 通过其技术委员会 45 (TC45) 执行的,来自 Apple、Barclays Capital、BP、The British Library、Essilor、Intel、Microsoft、NextPage、Novell、Statoil、Toshiba 和 United States Library of Congress 的代表参与了该项工作。该标准旨在提供现有 ISO 标准所无法提供的独特好处,其中包括能够实现从现有二进制格式向基于 XML 的格式的高保真移植。
OpenXml 官方文档
https://github.com/OfficeDev/Open-XML-SDK
如何使用
在 Hoa Framework 中,基于标准的 OpenXml/ClosedXML 开发的快捷Excel操作方式,可以大大减少Excel的复杂度以及大数据导出性能过高问题。
下面分为两个章节介绍 Excel 导入导出功能。
注入 IWorkbookContext 实例
首先在 Hoa.Applicaiton.HoaApplicationModule.cs
中注入 实例,如:
builder.RegisterGeneric(typeof(WorkbookContext<>))
.As(typeof(IWorkbookContext<>));
关于 IWorkbookContext 接口
IWorkbookContext<T>/WorkbookContext<T>
是Hoa Framework 框架独创的操作Excel上下文对象,该对象有三个方法,使用非常简单。
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace Hoa.Workbook
{
public interface IWorkbookContext<T> : IDisposable
{
// 导出并保存到文件中
Task ExportToSaveAsync(string fileName, IEnumerable<T> datas);
// 导出并保存到文件中(重载)
Task ExportToSaveAsync(string fileName, params T[] datas);
// 导出到内存流中
Task<MemoryStream> ExportToMemoryStreamAsync(IEnumerable<T> datas);
// 导出到内存流中(重载)
Task<MemoryStream> ExportToMemoryStreamAsync(params T[] datas);
// 导出到MVC的FileStreamResult中,可直接配合MVC下载
Task<FileStreamResult> ExportToFileStreamResultAsync(string fileDownloadName, IEnumerable<T> datas);
// 导出到MVC的FileStreamResult中,可直接配合MVC下载(重载)
Task<FileStreamResult> ExportToFileStreamResultAsync(string fileDownloadName, params T[] datas);
}
}
Excel 导出
导出基本类型

using Hoa.Workbook;
using Hoa.Workbook.Enums;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace Hoa.Web.Host.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HoaController : ControllerBase
{
private readonly IWorkbookContext<object> _workbookContext;
public HoaController(
IWorkbookContext<object> workbookContext
{
_workbookContext = workbookContext;
}
[HttpGet]
[Route(nameof(ExportValueType))]
public async Task ExportValueType()
{
await _workbookContext.ExportToSaveAsync("object.xlsx",
1, // int
1d, // double
10f, // float
1m, // decimal
true, // bool
false, // bool
DateTime.Now, // DateTime
100000000000000000, // long
1.9, // number
BorderStyle.DashDot, // enum
"string type" // string
);
}
}
}
导出强类型

using Hoa.Workbook;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Hoa.Web.Host.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HoaController : ControllerBase
{
private readonly IWorkbookContext<Person> _workbookContext;
public HoaController(
IWorkbookContext<Person> workbookContext)
{
_workbookContext = workbookContext;
}
[HttpGet]
[Route(nameof(ExportValueType))]
public async Task ExportValueType()
{
var persons = new List<Person>()
{
new Person(){Id=1,Name="Monk",Age=27,Address="广东省珠海市香洲区" },
new Person(){Id=2,Name="Suncoder",Age=22,Address="广东省中山市石岐区" },
new Person(){Id=3,Name="Cocoli",Age=30,Address="香港自治区" },
new Person(){Id=4,Name="Steft",Age=45,Address="广西省安宁市某某乡镇" },
new Person(){Id=5,Name="Dave",Age=35,Address="广东省珠海市南方软件园" },
new Person(){Id=6,Name="Teyn",Age=20,Address="澳门经济特区" }
};
await _workbookContext.ExportToSaveAsync("persons", persons);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
}
更加丰富页面导出

using Hoa.Workbook;
using Hoa.Workbook.Attributes;
using Hoa.Workbook.Enums;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Hoa.Web.Host.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HoaController : ControllerBase
{
private readonly IWorkbookContext<Person> _workbookContext;
public HoaController(
IWorkbookContext<Person> workbookContext)
{
_workbookContext = workbookContext;
}
[HttpGet]
[Route(nameof(ExportValueType))]
public async Task ExportValueType()
{
var persons = new List<Person>()
{
new Person(){Id=1,Name="Monk",Age=27,Address="广东省珠海市香洲区",Photo=@"C:\images\bxs.jpg",Site="https://monksoul.gitbook.io/",PhoneNumber="13800138000" },
new Person(){Id=2,Name="Suncoder",Age=22,Address="广东省中山市石岐区" ,Photo=@"C:\images\xtx.jpg",Site="https://www.baidu.com/",PhoneNumber="18676675647" },
new Person(){Id=3,Name="Cocoli",Age=30,Address="香港自治区",Photo=@"C:\images\bxs.jpg",Site="https://www.google.com/",PhoneNumber="16609987544" },
new Person(){Id=4,Name="Steft",Age=45,Address="广西省安宁市某某乡镇",Photo=@"C:\images\xtx.jpg",Site="https://www.cnblogs.com/",PhoneNumber="13476437890" },
new Person(){Id=5,Name="Dave",Age=35,Address="广东省珠海市南方软件园",Photo=@"C:\images\bxs.jpg",Site="https://www.ithome.com/",PhoneNumber="16773467833" },
new Person(){Id=6,Name="Teyn",Age=20,Address="澳门经济特区",Photo=@"C:\images\xtx.jpg",Site="https://www.csdn.net/",PhoneNumber="18934568890" }
};
await _workbookContext.ExportToSaveAsync("persons", persons);
}
}
[Excel("员工列表", "绩效列表")]
[ExcelGroup("员工列表汇总", BackgroundColor = "#cccccc", Height = 30)]
[ExcelHead(BackgroundColor = "#dedede", Height = 25)]
[ExcelRow(-1, Height = 50, BackgroundColor = "#d9d9d9")]
[ExcelRow(-2, Height = 50, BackgroundColor = "#f0f0f0")]
public class Person
{
[ExcelCell("编号")]
public int Id { get; set; }
[ExcelCell("名称", FontBold = true, BackgroundColor = "#f5f5f5", FontColor = "#ff0000")]
public string Name { get; set; }
[ExcelCell("年龄", AlignmentHorizontal = Workbook.Enums.HorizontalAlignment.Right)]
public int Age { get; set; }
[ExcelCell("地址", Width = 30)]
public string Address { get; set; }
[ExcelCell("头像", CellType = Workbook.Enums.CellType.Image, ImageScale = 0.06, AlignmentHorizontal = HorizontalAlignment.Center, AlignmentVertical = VerticalAlignment.Center)]
public string Photo { get; set; }
[ExcelCell("个人主页", CellType = Workbook.Enums.CellType.Hyperlink, Tooltip = "这是是我个人主页", Width = 30)]
public string Site { get; set; }
[ExcelCell("联系方式", Format = "###,###,####", Width = 30, OutsideBorder = new object[] { BorderStyle.DashDot, "#0000ff" })]
public string PhoneNumber { get; set; }
}
}
导出并下载到本地
using Hoa.Workbook;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace Hoa.Web.Host.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HoaController : ControllerBase
{
private readonly IWorkbookContext<object> _workbookContext;
public HoaController(IWorkbookContext<object> workbookContext)
{
_workbookContext = workbookContext;
}
[HttpGet]
[Route(nameof(DownloadFile))]
public async Task<IActionResult> DownloadFile()
{
var fileStreamResult = await _workbookContext.ExportToFileStreamResultAsync("test.xlsx", 1, 2, 3, 4, true, false);
return fileStreamResult;
}
}
}
前端Angular下载示例
Get请求
只需要通过 <a href='下载地址'>下载</a>
即可。
Post请求
// 导入HttpClient/HttpResponse 包
import { HttpClient, HttpResponse } from '@angular/common/http';
// 构造函数初始化
constructor(
private httpClient: HttpClient
) { }
// 下载,第一个参数为post地址,第二个参数为post参数
this.httpClient.post('http://localhost:57310/api/Member/ExportMemberClaims', [{}], {
responseType: 'blob',
observe: 'events',
}).subscribe((res: HttpResponse<Blob>) => {
if (res.type !== 4) { return; }
const objUrl = window.URL.createObjectURL(res.body);
const a = document.createElement('a');
a.href = objUrl;
const fileName = 'excel.xlsx'; // 设置下载文件名
a.download = decodeURIComponent(fileName);
a.click();
window.URL.revokeObjectURL(objUrl);
});
更多功能
更多功能不断集成开发中,敬请期待。
特性说明
[Excel] 特性配置
配置Excel使用区域信息、样式。
SheetNames
:配置Excel多个SheetScale
:配置每个Sheet数据比例,比如有两个Sheet,数据有1000条,则:1:3
表示第一个Sheet有250条,第二个Sheet有750条。OutsideBorder
:配置数据外边框样式,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串InsideBorder
:配置数据内边框样式,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串AdjustToContents
:是否自动调整内容宽度
[ExcelCell] 特性配置
配置单元格信息、样式。
Name
:配置列名,不配置采用属性名BackgroundColor
:背景颜色CellType
:单元格类型,有(Text:文本类型,Image:图片类型,HyperLink:链接类型)Hyperlink
:链接值,如果等于@Value
则取单元格的值,只有 CellType=HyperLink有效Tooltip
:链接获取焦点提示,只有 CellType=HyperLink有效ImageScale
:图片缩放比例,只有 CellType=Image有效AlignmentHorizontal
:单元格数据水平对其方式AlignmentVertical
:单元格数据垂直对其方式FontSize
:字体大小FontBold
:是否加粗FontColor
:字体颜色Width
:单元格宽度OutsideBorder
:单元格外边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串InsideBorder
:单元格内边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串Border
:单元格四个方向边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串,第三个参数是方向BorderDirection
枚举类型SetToColumnStyle
:是否将单元格样式设置给全局列Format
:单元格内容格式,支持OpenXml和StringFormat格式
[ExcelGroup] 特性配置
配置分组单元格信息、样式。
Name
:配置列名,不配置采用属性名BackgroundColor
:背景颜色CellType
:单元格类型,有(Text:文本类型,Image:图片类型,HyperLink:链接类型)Hyperlink
:链接值,如果等于@Value
则取单元格的值,只有 CellType=HyperLink有效Tooltip
:链接获取焦点提示,只有 CellType=HyperLink有效ImageScale
:图片缩放比例,只有 CellType=Image有效AlignmentHorizontal
:单元格数据水平对其方式AlignmentVertical
:单元格数据垂直对其方式FontSize
:字体大小FontBold
:是否加粗FontColor
:字体颜色Height
:单元格高度OutsideBorder
:单元格外边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串InsideBorder
:单元格内边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串Border
:单元格四个方向边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串,第三个参数是方向BorderDirection
枚举类型SetToColumnStyle
:是否将单元格样式设置给全局列Format
:单元格内容格式,支持OpenXml和StringFormat格式
[ExcelHead] 特性配置
配置表头信息、样式。
BackgroundColor
:背景颜色AlignmentHorizontal
:单元格数据水平对其方式AlignmentVertical
:单元格数据垂直对其方式FontSize
:字体大小FontBold
:是否加粗FontColor
:字体颜色Height
:单元格高度OutsideBorder
:单元格外边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串InsideBorder
:单元格内边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串Border
:单元格四个方向边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串,第三个参数是方向BorderDirection
枚举类型Format
:单元格内容格式,支持OpenXml和StringFormat格式
[ExcelRow] 特性配置
Index
:行索引,(0:不做任何行操作,> 0:特性行操作,-1/-2:奇偶行操作)Name
:行的名字(暂未启用该功能)BackgroundColor
:背景颜色AlignmentHorizontal
:单元格数据水平对其方式AlignmentVertical
:单元格数据垂直对其方式FontSize
:字体大小FontBold
:是否加粗FontColor
:字体颜色Height
:单元格高度OutsideBorder
:单元格外边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串InsideBorder
:单元格内边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串Border
:单元格四个方向边框,对象数组类型,数组第一个参数为BorderStyle
枚举,第二个参数为 颜色值字符串,第三个参数是方向BorderDirection
枚举类型
Excel 导入
最后更新于
这有帮助吗?