如何用excel导出上市公司财务报表?

导出自选股找到自选股所在的位置,这里以同花顺自选港股为例。一、点击“自选股”,在下方找到要导出的板块。二、点击“所属行业”进行排列,导出后可以进行行业比较。三、选择任何一只股票,右......

如何用excel导出上市公司财务报表

前言我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作。在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程......接下来具体说说

Spring Boot框架下实现Excel服务端导入导出

如何用excel导出上市公司财务报表?

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。今天我们就使用SpreadJS带大家了解,如何在Spring Boot框架下实现Excel服务端导入导出。

SpreadJS作为一款纯前端控件,对任何框架都没有限制,可以自由地和各种框架进行集成,实现类似 Excel 的电子表格功能,如公式计算、图表、在线导入导出和数据透视表,使应用程序具备“在线 Excel”的能力。

如何用excel导出上市公司财务报表?

(图片来源于网络)

1.IDEA创建SpringBoot项目

1.1 Spring Initializr

想要在IDEA下快速搭建一个SpringBoot项目,可以使用Spring Initializr工具作为脚手架。

进入IDEA后,在左侧菜单中可以找到Plugins,点击后,在上方的搜索框中输入Spring Initializr。

之后点击右上角的绿色Install按钮进行安装。

如何用excel导出上市公司财务报表?

(安装)

安装完毕后,在New Project 的时候就会多一个Spring Initializr的选项。

如何用excel导出上市公司财务报表?

(安装完成)

1.2 SpringBoot 项目的创建

Project SDK:根据实际应用情况选择用于配置项目所依赖的Java SDK。

Choose Spring Initializr Server:选择一个Spring Initializr服务器,一般来说都选择默认的。

如何用excel导出上市公司财务报表?

(项目创建)

GroupId:一般分为多个段,靠前段为域,第二段为公司名称。例如:org.apache,com.grapecity。

ArtifactId:是项目的唯一标识符,在实际开发中一般对应项目的名称,就是项目根目录的名称。

Group Id,Artfact Id是保证项目唯一性的标识,一般来说如果项目打包上传至maven这样的包管理仓库中。在搜索你的项目时,Group Id,Artfact Id是必要的条件。

Version:版本号,默认0.0.1-SNAPSHOT。SNAPSHOT代表不稳定的版本,与之相对的有RELEASE。

Project type:工程的类型,maven工程还是gradle工程。

Language:语言(Java,Kotlin,Groovy)。

Packaging:Jar包还是War包。

Java version:语法版本,与Project SDK不同,Project SDK是实际用到的JDK。Java version指的是语法版本。一般来说语言特性不能比SDK高。比如SDK版本是11,语法选择8。那么实际项目中只能使用java 8的语法。反之SDK版本是8,语法选11就有问题了。一般情况下都会与SDK保持一致。

Project name:项目名称

Project description:项目描述

Package name:包名

(包命名)

(具体配置)

第三部分根据项目的实际需求去配置。

(需求配置)

第四部分:

设置项目名称与路径。

2.前端配置

考虑到导入导出功能需要对Excel具有较高的还原度,这里使用了SpreadJS组件,通过SpreadJS组件的ExcelIO功能,进行Excel的导入与导出。SpreadJS是一款纯前端的组件,与后端完全解耦,可以完美的整合到SpringBoot工程中。

2.1 前端页面创建

在static目录下建立index.html文件,用来绘制前端页面。如果用了thymeleaf也可以将文件建立在templates目录中。

2.1 SpreadJS组件引入和初始化

在header中引入SpreadJS相关的css与js引用。

创建SpreadJS对应的DOM对象。

在JS中初始化SpreadJS和导入导出Excel相关的ExcelIO对象。

通过按钮点击进行服务端导入与导出。

导入导出事件处理,在事件中发送请求与服务端进行连接。

导入原理:

将服务端的文件以文件流的形式传输至前端,前端通过ExcelIO将结果导入结果呈现值SpreadJS中,所以导入的传递的参数是一个文件路径。注意该路径是文件在服务端或者工程中的一个路径。

导出原理:

通过SpreadJS ExcelIO的功能将内容导出成Excel的blob流。之后将blob流传至服务器端,在服务器端进行保存Excel文件的操作。

3.后端配置

创建后端controller,可按照自身项目的包的层级分类进行创建。

构建服务端的导入导出方法和相关逻辑。

服务器端导入:

由于前端传入的是一个文件的路径,所以参数这里我们需要一个字符串类型的参数去接收。

另外,我们会将流传到前端,所以会将流写到response中,所以参数中还需要response对象,方法本身不需要返回,返回空即可。原理是通过inputStream读取文件后,将其写入response的outputStream中。

导出到服务器:

由于前端传入传入的是保存文件的名称以及文件blob文件流。服务器端需要两个参数,String用来接收文件名称,MultipartFile对象用来接收blob文件流。后端接受到文件流之后通过transferTo方法在指定目录下根军传来的fileName转存成新的文件。

4.测试运行

将工程跑起来之后进入主页面,显示如下:

点击服务端导入按钮,从服务器端下载指定的Excel文件并打开。

对该文件进行操作修改并点击服务端导出的按钮。

之后我们去服务器端的导出路径下查看,发下文件存在,用Excel打开文件后发现,修改后的内容健在并且其他内容显示均无问题。

如何导出自选股,用Excel表格进行统计和分析?

导出自选股

找到自选股所在的位置,这里以同花顺自选港股为例。

一、点击“自选股”,在下方找到要导出的板块。

二、点击“所属行业”进行排列,导出后可以进行行业比较。

三、选择任何一只股票,右键-“数据导出”-“导出所有数值”

四、选择要导出的位置,以Excel文件导出,然后点击“下一步”。

五、选择要导出的数据,这里导出“代码、名称、TTM市盈率、市净率、港股通持股量、占H股%和所属行业”为例,然后点击下一步,便完成自选股Excel导出。

设计估值方案

每个人对股票的估值方法不同,这也就导致每个人的估值方案不同。

依巴菲特的选股理念,注重的是高ROE(净资产收益率)和低PE(市盈率)。

那么我们可以根据:PE=每股收益/股价;PB=股价/每股净资产;ROE=每股收益/每股净资产。

推断出:PB=ROE*PE和ROE=PB/PE。

这里以ROE>15%为关注对象,ROE*100/PE>2为低估,可多仓为对象;ROE*100/PE<1/2为高估,可空仓为对象;设计估值方案。

利用Excel统计和分析自选股

一、打开导出的数据,在H1填写“ROE”,I1填写“ROE>15%”,J1填写“多空”

二、H2填写“=D2/C2”,并右键设置单元格,将数据改成百分比,然后右下角下拉,自动填充。

三、借用函数IF(可以在公式常用函数中找到),分别填入数值,或直接在I2中填入“=IF(H2>15%,"关注","不")”,意思是,当H2大于15%时,返回“关注”,否则返回“不”,然后下拉,自动填充,如图。

四、确定估值,以及标注可操作方向。

同样选择IF函数,或可在J2直接填入“=IF(H2*100/C2>2,"多",IF(H2*100/C2<1/2,"空","不理会"))”。

这是嵌套公式,意思是H2*100/C2>2时,显示为多;否则,则进入下一假设;下一假设中,当H2*100/C2<1/2时,显示空,否则显示不理会。

重要数据给予颜色标记

一、ROE>15%给予红色标记

1、点击“开始”-“条件格式”-“突出显示单元格规则”-“文本包含”

2、在对话框中填入要标注的文字,这里以“关注”为对象,然后点确定,下拉单元格,便可以将需要关注的标记为红色

二、给多标记为红色和给空标记为绿色

方法同上,这里就不再赘述了。

三、给TTM市盈率<10,标记为红色

1、选择C整列,然后点击“开始”-“条件格式”-“突出显示单元格规则”-“小于”

2、对话框中输入10

3、点击确定即可

NET Core 实现Excel的导入导出

前言

我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作。在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程。但是直接使用Npoi大部分时候我们可能都会自己封装一下,毕竟根据二八原则,我们百分之八十的场景可能都是进行简单的导入导出操作,这里就引出我们的主角Npoi。

NPOI简介

NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目。

一、安装相对应的程序包

在 .Net Core 中使用NPOI首先必须先安装NPOI;如下图所示:

1.1、在 “管理NuGet程序包” 中的浏览搜索:“NPOI”

点击安装以上两个即可, 安装完成之后较好重新编译一下项目以防出错

二、新建Excel帮助类

在项目中新建“ExcelHelper”类;此类用于封装导入导出以及其他配置方法。代码如下:

using System;using System.Collections.Generic;using System.Data;using System.IO;using NPOI;using System.Text;using NPOI.HSSF.UserModel;using NPOI.XSSF.UserModel;using NPOI.SS.Formula.Eval;using NPOI.SS.UserModel;using NPOI.SS.Util;using System.Text.RegularExpressions;using System.Reflection;using System.Collections;using NPOI.HSSF.Util;namespace WebApplication1 //命名空间依据自己的项目进行修改{ /// <summary> /// Excel帮助类 /// 功能: /// 1、导出数据到Excel文件中 /// 2、将Excel文件的数据导入到List<T>对象集合中 /// </summary> public static class ExcelHelper { /// <summary> /// 导出列名 /// </summary> public static SortedList ListColumnsName; #region 从DataTable导出到excel文件中,支持xls和xlsx格式 #region 导出为xls文件内部方法 /// <summary> /// 从DataTable 中导出到excel /// </summary> /// <param name="strFileName">excel文件名</param> /// <param name="dtSource">datatabe源数据</param> /// <param name="strHeaderText">表名</param> /// <param name="sheetnum">sheet的编号</param> /// <returns></returns> static MemoryStream ExportDT(string strFileName, DataTable dtSource, string strHeaderText, Dictionary<string, string> dir, int sheetnum) { //创建工作簿和sheet IWorkbook workbook = new HSSFWorkbook(); using (Stream writefile = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read)) { if (writefile.Length > 0 && sheetnum > 0) { workbook = WorkbookFactory.Create(writefile); } } ISheet sheet = null; ICellStyle dateStyle = workbook.CreateCellStyle(); IDataFormat format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); int[] arrColWidth = new int[dtSource.Columns.Count]; foreach (DataColumn item in dtSource.Columns) { arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length; } for (int i = 0; i < dtSource.Rows.Count; i++) { for (int j = 0; j < dtSource.Columns.Count; j++) { int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } int rowIndex = 0; foreach (DataRow row in dtSource.Rows) { #region 新建表,填充表头,填充列头,样式 if (rowIndex == 0) { string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString()); if (workbook.GetSheetIndex(sheetName) >= 0) { workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName)); } sheet = workbook.CreateSheet(sheetName); #region 表头及样式 { sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1)); IRow headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(strHeaderText); ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; rowIndex = 1; } #endregion #region 列头及样式 if (rowIndex == 1) { IRow headerRow = sheet.CreateRow(1);//第二行设置列名 ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); //写入列标题 foreach (DataColumn column in dtSource.Columns) { headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]); headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //设置列宽 sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2); } rowIndex = 2; } #endregion } #endregion #region 填充内容 IRow dataRow = sheet.CreateRow(rowIndex); foreach (DataColumn column in dtSource.Columns) { NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal); string drValue = row[column].ToString(); switch (column.DataType.ToString()) { case "System.String": //字符串类型 double result; if (isNumeric(drValue, out result)) { //数字字符串 double.TryParse(drValue, out result); newCell.SetCellValue(result); break; } else { newCell.SetCellValue(drValue); break; } case "System.DateTime": //日期类型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle; //格式化显示 break; case "System.Boolean": //布尔型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell.SetCellValue(boolV); break; case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); break; case "System.DBNull": //空值处理 newCell.SetCellValue(""); break; default: newCell.SetCellValue(drValue.ToString()); break; } } #endregion rowIndex++; } using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms, true); ms.Flush(); ms.Position = 0; return ms; } } #endregion #region 导出为xlsx文件内部方法 /// <summary> /// 从DataTable 中导出到excel /// </summary> /// <param name="dtSource">DataTable数据源</param> /// <param name="strHeaderText">表名</param> /// <param name="fs">文件流</param> /// <param name="readfs">内存流</param> /// <param name="sheetnum">sheet索引</param> static void ExportDTI(DataTable dtSource, string strHeaderText, FileStream fs, MemoryStream readfs, Dictionary<string, string> dir, int sheetnum) { IWorkbook workbook = new XSSFWorkbook(); if (readfs.Length > 0 && sheetnum > 0) { workbook = WorkbookFactory.Create(readfs); } ISheet sheet = null; ICellStyle dateStyle = workbook.CreateCellStyle(); IDataFormat format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); //取得列宽 int[] arrColWidth = new int[dtSource.Columns.Count]; foreach (DataColumn item in dtSource.Columns) { arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length; } for (int i = 0; i < dtSource.Rows.Count; i++) { for (int j = 0; j < dtSource.Columns.Count; j++) { int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } int rowIndex = 0; foreach (DataRow row in dtSource.Rows) { #region 新建表,填充表头,填充列头,样式 if (rowIndex == 0) { #region 表头及样式 { string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString()); if (workbook.GetSheetIndex(sheetName) >= 0) { workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName)); } sheet = workbook.CreateSheet(sheetName); sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1)); IRow headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(strHeaderText); ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; } #endregion #region 列头及样式 { IRow headerRow = sheet.CreateRow(1); ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = HorizontalAlignment.Center; IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); foreach (DataColumn column in dtSource.Columns) { headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]); headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //设置列宽 sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2); } } #endregion rowIndex = 2; } #endregion #region 填充内容 IRow dataRow = sheet.CreateRow(rowIndex); foreach (DataColumn column in dtSource.Columns) { NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal); string drValue = row[column].ToString(); switch (column.DataType.ToString()) { case "System.String": //字符串类型 double result; if (isNumeric(drValue, out result)) { double.TryParse(drValue, out result); newCell.SetCellValue(result); break; } else { newCell.SetCellValue(drValue); break; } case "System.DateTime": //日期类型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle; //格式化显示 break; case "System.Boolean": //布尔型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell.SetCellValue(boolV); break; case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); break; case "System.DBNull": //空值处理 newCell.SetCellValue(""); break; default: newCell.SetCellValue(drValue.ToString()); break; } } #endregion rowIndex++; } workbook.Write(fs,true); fs.Close(); } #endregion #region 导出excel表格 /// <summary> /// DataTable导出到Excel文件,xls文件 /// </summary> /// <param name="dtSource">数据源</param> /// <param name="strHeaderText">表名</param> /// <param name="strFileName">excel文件名</param> /// <param name="dir">DataTable和excel列名对应字典</param> /// <param name="sheetRow">每个sheet存放的行数</param> public static void ExportDTtoExcel(DataTable dtSource, string strHeaderText, string strFileName, Dictionary<string, string> dir, bool isNew, int sheetRow = 50000) { int currentSheetCount = GetSheetNumber(strFileName);//现有的页数sheetnum if (sheetRow <= 0) { sheetRow = dtSource.Rows.Count; } string[] temp = strFileName.Split('.'); string fileExtens = temp[temp.Length - 1]; int sheetCount = (int)Math.Ceiling((double)dtSource.Rows.Count / sheetRow);//sheet数目 if (temp[temp.Length - 1] == "xls" && dtSource.Columns.Count < 256 && sheetRow < 65536) { if (isNew) { currentSheetCount = 0; } for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++) { DataTable pageDataTable = dtSource.Clone(); int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow; for (int j = 0; j < hasRowCount; j++) { pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]); } using (MemoryStream ms = ExportDT(strFileName, pageDataTable, strHeaderText, dir, i)) { using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)) { byte[] data = ms.ToArray(); fs.Write(data, 0, data.Length); fs.Flush(); } } } } else { if (temp[temp.Length - 1] == "xls") strFileName = strFileName + "x"; if (isNew) { currentSheetCount = 0; } for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++) { DataTable pageDataTable = dtSource.Clone(); int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow; for (int j = 0; j < hasRowCount; j++) { pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]); } FileStream readfs = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read); MemoryStream readfsm = new MemoryStream(); readfs.CopyTo(readfsm); readfs.Close(); using (FileStream writefs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)) { ExportDTI(pageDataTable, strHeaderText, writefs, readfsm, dir, i); } readfsm.Close(); } } } /// <summary> /// 导出Excel(//超出10000条数据 创建新的工作簿) /// </summary> /// <param name="dtSource">数据源</param> /// <param name="dir">导出Excel表格的字段名和列名的字符串字典实例;例如:dir.Add("IllegalKeywords", "姓名");</param> public static XSSFWorkbook ExportExcel(DataTable dtSource, Dictionary<string, string> dir) { XSSFWorkbook excelWorkbook = new XSSFWorkbook(); //int columnsCount = columnsNames.GetLength(0); int columnsCount = dir.Count; if (columnsCount > 0) { ListColumnsName = new SortedList(new NoSort()); //for (int i = 0; i < columnsCount; i++) //{ // ListColumnsName.Add(columnsNames[i, 0], columnsNames[i, 1]); //} foreach (KeyValuePair<string,string> item in dir) { ListColumnsName.Add(item.Key, item.Value); } if (ListColumnsName == null || ListColumnsName.Count == 0) { throw (new Exception("请对ListColumnsName设置要导出的列明!")); } else { excelWorkbook = InsertRow(dtSource); } } else { throw (new Exception("请对ListColumnsName设置要导出的列明!")); } return excelWorkbook; } #endregion /// <summary> /// 创建Excel文件 /// </summary> /// <param name="filePath"></param> private static XSSFWorkbook CreateExcelFile() { XSSFWorkbook xssfworkbook = new XSSFWorkbook(); //右击文件“属性”信息 #region 文件属性信息 { POIXMLProperties props = xssfworkbook.GetProperties(); props.CoreProperties.Creator = "Joy";//Excel文件的创建作者 props.CoreProperties.Title = "";//Excel文件标题 props.CoreProperties.Description = "";//Excel文件备注 props.CoreProperties.Category = "";//Excel文件类别信息 props.CoreProperties.Subject = "";//Excel文件主题信息 props.CoreProperties.Created = DateTime.Now;//Excel文件创建时间 props.CoreProperties.Modified = DateTime.Now;//Excel文件修改时间 props.CoreProperties.SetCreated(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); props.CoreProperties.LastModifiedByUser = "Joy";//Excel文件最后一次保存者 props.CoreProperties.SetModified(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//Excel文件最后一次保存日期 } #endregion return xssfworkbook; } /// <summary> /// 创建excel表头 /// </summary> /// <param name="dgv"></param> /// <param name="excelSheet"></param> private static void CreateHeader(XSSFSheet excelSheet, XSSFWorkbook excelWorkbook, XSSFCellStyle cellStyle) { int cellIndex = 0; //循环导出列 foreach (System.Collections.DictionaryEntry de in ListColumnsName) { XSSFRow newRow = (XSSFRow)excelSheet.CreateRow(0); XSSFCellStyle? headTopStyle = CreateStyle(excelWorkbook, cellStyle,HorizontalAlignment.Center, VerticalAlignment.Center, 18, true, true, "宋体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.Grey25Percent.Index, HSSFColor.Black.Index,FontUnderlineType.None, FontSuperScript.None, false); XSSFCell newCell = (XSSFCell)newRow.CreateCell(cellIndex); newCell.SetCellValue(de.Value.ToString()); newCell.CellStyle = headTopStyle; cellIndex++; } } /// <summary> /// **数据行 /// </summary> private static XSSFWorkbook InsertRow(DataTable dtSource) { XSSFWorkbook excelWorkbook = CreateExcelFile(); int rowCount = 0; int sheetCount = 1; XSSFSheet newsheet = null; //循环数据源导出数据集 newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount); XSSFCellStyle headCellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建列头单元格实例样式 CreateHeader(newsheet, excelWorkbook, headCellStyle); //单元格内容信息 foreach (DataRow dr in dtSource.Rows) { rowCount++; //超出10000条数据 创建新的工作簿 if (rowCount == 10000) { rowCount = 1; sheetCount++; newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount); CreateHeader(newsheet, excelWorkbook, headCellStyle); } XSSFRow newRow = (XSSFRow)newsheet.CreateRow(rowCount); XSSFCellStyle cellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建单元格实例样式 XSSFCellStyle? style = CreateStyle(excelWorkbook, cellStyle, HorizontalAlignment.Center, VerticalAlignment.Center, 14, true, false); InsertCell(dtSource, dr, newRow, style, excelWorkbook); } //自动列宽 //for (int i = 0; i <= dtSource.Columns.Count; i++) //{ // newsheet.AutoSizeColumn(i, true); //} return excelWorkbook; } /// <summary> /// 导出数据行 /// </summary> /// <param name="dtSource"></param> /// <param name="drSource"></param> /// <param name="currentExcelRow"></param> /// <param name="excelSheet"></param> /// <param name="excelWorkBook"></param> private static void InsertCell(DataTable dtSource, DataRow drSource, XSSFRow currentExcelRow, XSSFCellStyle cellStyle, XSSFWorkbook excelWorkBook) { for (int cellIndex = 0; cellIndex < ListColumnsName.Count; cellIndex++) { //列名称 string columnsName = ListColumnsName.GetKey(cellIndex).ToString(); XSSFCell newCell = null; System.Type rowType = drSource[columnsName].GetType(); string drValue = drSource[columnsName].ToString().Trim(); switch (rowType.ToString()) { case "System.String"://字符串类型 drValue = drValue.Replace("&", "&"); drValue = drValue.Replace(">", ">"); drValue = drValue.Replace("<", "<"); newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(drValue); newCell.CellStyle = cellStyle; break; case "System.DateTime"://日期类型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(dateV); newCell.CellStyle = cellStyle; break; case "System.Boolean"://布尔型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(boolV); newCell.CellStyle = cellStyle; break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(intV.ToString()); newCell.CellStyle = cellStyle; break; case "System.Decimal"://浮点型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(doubV); newCell.CellStyle = cellStyle; break; case "System.DBNull"://空值处理 newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex); newCell.SetCellValue(""); newCell.CellStyle = cellStyle; break; default: throw (new Exception(rowType.ToString() + ":类型数据无法处理!")); } } } /// <summary> /// 行内单元格常用样式设置 /// </summary> /// <param name="workbook">Excel文件对象</param> /// <param name="cellStyle">Excel文件中XSSFCellStyle对象</param> /// <param name="hAlignment">水平布局方式</param> /// <param name="vAlignment">垂直布局方式</param> /// <param name="fontHeightInPoints">字体大小</param> /// <param name="isAddBorder">是否需要边框</param> /// <param name="boldWeight">字体加粗 (None = 0,Normal = 400,Bold = 700</param> /// <param name="fontName">字体(仿宋,楷体,宋体,微软雅黑...与Excel主题字体相对应)</param> /// <param name="isAddBorderColor">是否增加边框颜色</param> /// <param name="isItalic">是否将文字变为斜体</param> /// <param name="isLineFeed">是否自动换行</param> /// <param name="isAddCellBackground">是否增加单元格背景颜色</param> /// <param name="fillPattern">填充图案样式(FineDots 细点,SolidForeground立体前景,isAddFillPattern=true时存在)</param> /// <param name="cellBackgroundColor">单元格背景颜色(当isAddCellBackground=true时存在)</param> /// <param name="fontColor">字体颜色</param> /// <param name="underlineStyle">下划线样式(无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting])</param> /// <param name="typeOffset">字体上标下标(普通默认值[None],上标[Sub],下标[Super]),即字体在单元格内的上下偏移量</param> /// <param name="isStrikeout">是否显示删除线</param> /// <param name="dataFormat">格式化日期显示</param> /// <returns></returns> public static XSSFCellStyle CreateStyle(XSSFWorkbook workbook, XSSFCellStyle cellStyle, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short fontHeightInPoints, bool isAddBorder, bool boldWeight, string fontName = "宋体", bool isAddBorderColor = true, bool isItalic = false, bool isLineFeed = true, bool isAddCellBackground = false, FillPattern fillPattern = FillPattern.NoFill, short cellBackgroundColor = HSSFColor.Yellow.Index, short fontColor = HSSFColor.Black.Index, FontUnderlineType underlineStyle = FontUnderlineType.None, FontSuperScript typeOffset = FontSuperScript.None, bool isStrikeout = false,string dataFormat="yyyy-MM-dd HH:mm:ss") { cellStyle.Alignment = hAlignment; //水平居中 cellStyle.VerticalAlignment = vAlignment; //垂直居中 cellStyle.WrapText = isLineFeed;//自动换行 //格式化显示 XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat(); cellStyle.DataFormat = format.GetFormat(dataFormat); //背景颜色,边框颜色,字体颜色都是使用 HSSFColor属性中的对应调色板索引,关于 HSSFColor 颜色索引对照表,详情参考:https://www.cnblogs.com/Brainpan/p/5804167.html //TODO:引用了NPOI后可通过ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式 //TODO:十分注意,要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置,否则是不会显示背景颜色 if (isAddCellBackground) { cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色 cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点,SolidForeground立体前景) } else { cellStyle.FillForegroundColor = HSSFColor.White.Index;//单元格背景颜色 } //是否增加边框 if (isAddBorder) { //常用的边框样式 None(没有),Thin(细边框,瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置] cellStyle.BorderBottom = BorderStyle.Thin; cellStyle.BorderRight = BorderStyle.Thin; cellStyle.BorderTop = BorderStyle.Thin; cellStyle.BorderLeft = BorderStyle.Thin; } //是否设置边框颜色 if (isAddBorderColor) { //边框颜色[上右下左顺序设置] cellStyle.TopBorderColor = XSSFFont.DEFAULT_FONT_COLOR;//DarkGreen(黑绿色) cellStyle.RightBorderColor = XSSFFont.DEFAULT_FONT_COLOR; cellStyle.BottomBorderColor = XSSFFont.DEFAULT_FONT_COLOR; cellStyle.LeftBorderColor = XSSFFont.DEFAULT_FONT_COLOR; } /** * 设置相关字体样式 */ var cellStyleFont = (XSSFFont)workbook.CreateFont(); //创建字体 //假如字体大小只需要是粗体的话直接使用下面该属性即可 //cellStyleFont.IsBold = true; cellStyleFont.IsBold = boldWeight; //字体加粗 cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小 cellStyleFont.FontName = fontName;//字体(仿宋,楷体,宋体 ) cellStyleFont.Color = fontColor;//设置字体颜色 cellStyleFont.IsItalic = isItalic;//是否将文字变为斜体 cellStyleFont.Underline = underlineStyle;//字体下划线 cellStyleFont.TypeOffset = typeOffset;//字体上标下标 cellStyleFont.IsStrikeout = isStrikeout;//是否有删除线 cellStyle.SetFont(cellStyleFont); //将字体绑定到样式 return cellStyle; } #endregion #region 从excel文件中将数据导出到List<T>对象集合 /// <summary> /// 将制定sheet中的数据导出到DataTable中 /// </summary> /// <param name="sheet">需要导出的sheet</param> /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param> /// <param name="dir">excel列名和DataTable列名的对应字典</param> /// <returns></returns> static DataTable ImportDt(ISheet sheet, int HeaderRowIndex, Dictionary<string, string> dir) { DataTable table = new DataTable(); IRow headerRow; int cellCount; try { //没有标头或者不需要表头用excel列的序号(1,2,3..)作为DataTable的列名 if (HeaderRowIndex < 0) { headerRow = sheet.GetRow(0); cellCount = headerRow.LastCellNum; for (int i = headerRow.FirstCellNum; i <= cellCount; i++) { DataColumn column = new DataColumn(Convert.ToString(i)); table.Columns.Add(column); } } //有表头,使用表头做为DataTable的列名 else { headerRow = sheet.GetRow(HeaderRowIndex); cellCount = headerRow.LastCellNum; for (int i = headerRow.FirstCellNum; i <cellCount; i++) { //如果excel某一列列名不存在:以该列的序号作为DataTable的列名,如果DataTable中包含了这个序列为名的列,那么列名为重复列名+序号 if (headerRow.GetCell(i) == null) { if (table.Columns.IndexOf(Convert.ToString(i)) > 0) { DataColumn column = new DataColumn(Convert.ToString("重复列名" + i)); table.Columns.Add(column); } else { DataColumn column = new DataColumn(Convert.ToString(i)); table.Columns.Add(column); } } //excel中的某一列列名不为空,但是重复了:对应的DataTable列名为“重复列名+序号” else if (table.Columns.IndexOf(headerRow.GetCell(i).ToString()) > 0) { DataColumn column = new DataColumn(Convert.ToString("重复列名" + i)); table.Columns.Add(column); } else //正常情况,列名存在且不重复:用excel中的列名作为DataTable中对应的列名 { string aaa = headerRow.GetCell(i).ToString(); string colName = dir.Where(s => s.Value == headerRow.GetCell(i).ToString()).First().Key; DataColumn column = new DataColumn(colName); table.Columns.Add(column); } } } int rowCount = sheet.LastRowNum; for (int i = (HeaderRowIndex + 1); i <= sheet.LastRowNum; i++)//excel行遍历 { try { IRow row; if (sheet.GetRow(i) == null)//如果excel有空行,则添加缺失的行 { row = sheet.CreateRow(i); } else { row = sheet.GetRow(i); } DataRow dataRow = table.NewRow(); for (int j = row.FirstCellNum; j <= cellCount; j++)//excel列遍历 { try { if (row.GetCell(j) != null) { switch (row.GetCell(j).CellType) { case CellType.String://字符串 string str = row.GetCell(j).StringCellValue; if (str != null && str.Length > 0) { dataRow[j] = str.ToString(); } else { dataRow[j] = default(string); } break; case CellType.Numeric://数字 if (DateUtil.IsCellDateFormatted(row.GetCell(j)))//时间戳数字 { dataRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue); } else { dataRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue); } break; case CellType.Boolean: dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue); break; case CellType.Error: dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue); break; case CellType.Formula://公式 switch (row.GetCell(j).CachedFormulaResultType) { case CellType.String: string strFORMULA = row.GetCell(j).StringCellValue; if (strFORMULA != null && strFORMULA.Length > 0) { dataRow[j] = strFORMULA.ToString(); } else { dataRow[j] = null; } break; case CellType.Numeric: dataRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue); break; case CellType.Boolean: dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue); break; case CellType.Error: dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue); break; default: dataRow[j] = ""; break; } break; default: dataRow[j] = ""; break; } } } catch (Exception exception) { //loger.Error(exception.ToString()); } } table.Rows.Add(dataRow); } catch (Exception exception) { //loger.Error(exception.ToString()); } } } catch (Exception exception) { //loger.Error(exception.ToString()); } return table; } /// <summary> /// DataTable 转换为List<T>对象集合 /// </summary> /// <typeparam name="TResult">类型</typeparam> /// <param name="dt">DataTable</param> /// <returns></returns> public static List<TResult> DataTableToList<TResult>(this DataTable dt) where TResult : class, new() { //创建一个属性的列表 List<PropertyInfo> prlist = new List<PropertyInfo>(); //获取TResult的类型实例 反射的入口 Type t = typeof(TResult); //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表 Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); }); //创建返回的集合 List<TResult> oblist = new List<TResult>(); foreach (DataRow row in dt.Rows) { //创建TResult的实例 TResult ob = new TResult(); //找到对应的数据 并赋值 prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); }); //放入到返回的集合中. oblist.Add(ob); } return oblist; } /// <summary> /// DataTable**为List集合 /// </summary> /// <typeparam name="T">实体对象</typeparam> /// <param name="dt">datatable表</param> /// <param name="isStoreDB">是否存入数据库datetime字段,date字段没事,取出不用判断</param> /// <returns>返回list集合</returns> private static List<T> DataTableToList<T>(DataTable dt, bool isStoreDB = true) { List<T> list = new List<T>(); Type type = typeof(T); //List<string> listColums = new List<string>(); PropertyInfo[] pArray = type.GetProperties(); //集合属性数组 foreach (DataRow row in dt.Rows) { T entity = Activator.CreateInstance<T>(); //新建对象实例 foreach (PropertyInfo p in pArray) { if (!dt.Columns.Contains(p.Name) || row[p.Name] == null || row[p.Name] == DBNull.Value) { continue; //DataTable列中不存在集合属性或者字段内容为空则,跳出循环,进行下个循环 } if (isStoreDB && p.PropertyType == typeof(DateTime) && Convert.ToDateTime(row[p.Name]) < Convert.ToDateTime("1753-01-01")) { continue; } try { var obj = Convert.ChangeType(row[p.Name], p.PropertyType);//类型强转,将table字段类型转为集合字段类型 p.SetValue(entity, obj, null); } catch (Exception) { // throw; } } list.Add(entity); } return list; } /// <summary> /// DataSet 转换成List /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ds"></param> /// <param name="tableIndext"></param> /// <returns></returns> private static List<T> DataTable2List<T>(DataTable dt) { //确认参数有效 if (dt == null || dt.Rows.Count <= 0) { return null; } IList<T> list = new List<T>(); //实例化一个list // 在这里写 获取T类型的所有公有属性。 注意这里仅仅是获取T类型的公有属性,不是公有方法,也不是公有字段,当然也不是私有属性 PropertyInfo[] tMembersAll = typeof(T).GetProperties(); for (int i = 0; i < dt.Rows.Count; i++) { //创建泛型对象。为什么这里要创建一个泛型对象呢?是因为目前我不确定泛型的类型。 T t = Activator.CreateInstance<T>(); //获取t对象类型的所有公有属性。但是我不建议吧这条语句写在for循环里,因为没循环一次就要获取一次,占用资源,所以建议写在外面 //PropertyInfo[] tMembersAll = t.GetType().GetProperties(); for (int j = 0; j < dt.Columns.Count; j++) { //遍历tMembersAll foreach (PropertyInfo tMember in tMembersAll) { //取dt表中j列的名字,并把名字转换成大写的字母。整条代码的意思是:如果列名和属性名称相同时赋值 if (dt.Columns[j].ColumnName.ToUpper().Equals(tMember.Name.ToUpper())) { //dt.Rows[i][j]表示取dt表里的第i行的第j列;DBNull是指数据库中当一个字段没有被设置值的时候的值,相当于数据库中的“空值”。 if (dt.Rows[i][j] != DBNull.Value) { //SetValue是指:将指定属性设置为指定值。 tMember是T泛型对象t的一个公有成员,整条代码的意思就是:将dt.Rows[i][j]赋值给t对象的tMember成员,参数详情请参照http://msdn.microsoft.com/zh-cn/library/3z2t396t(v=vs.100).aspx/html tMember.SetValue(t, Convert.ToString(dt.Rows[i][j]), null); } else { tMember.SetValue(t, null, null); } break;//注意这里的break是写在if语句里面的,意思就是说如果列名和属性名称相同并且已经赋值了,那么我就跳出foreach循环,进行j+1的下次循环 } } } list.Add(t); } dt.Dispose(); return list.ToList(); } /// <summary> /// 读取Excel文件特定名字sheet的内容到List<T>对象集合 /// </summary> /// <param name="strFileName">excel文件路径</param> /// <param name="dir">excel列名和DataTable列名的对应字典</param> /// <param name="SheetName">excel表名</param> /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param> /// <returns></returns> public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, string SheetName, int HeaderRowIndex = 0) { DataTable table = new DataTable(); using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) { if (file.Length > 0) { IWorkbook wb = WorkbookFactory.Create(file); ISheet isheet = wb.GetSheet(SheetName); table = ImportDt(isheet, HeaderRowIndex, dir); isheet = null; } } List<T> results = DataTableToList<T>(table); table.Dispose(); return results; } /// <summary> /// 读取Excel文件某一索引sheet的内容到DataTable /// </summary> /// <param name="strFileName">excel文件路径</param> /// <param name="sheet">需要导出的sheet序号</param> /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param> /// <param name="dir">excel列名和DataTable列名的对应字典</param> /// <returns></returns> public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, int HeaderRowIndex = 0, int SheetIndex = 0) { DataTable table = new DataTable(); using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) { if (file.Length > 0) { IWorkbook wb = WorkbookFactory.Create(file); ISheet isheet = wb.GetSheetAt(SheetIndex); table = ImportDt(isheet, HeaderRowIndex, dir); isheet = null; } } List<T> results = DataTableToList<T>(table); table.Dispose(); return results; } #endregion /// <summary> /// 获取excel文件的sheet数目 /// </summary> /// <param name="outputFile"></param> /// <returns></returns> public static int GetSheetNumber(string outputFile) { int number = 0; using (FileStream readfile = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Read)) { if (readfile.Length > 0) { IWorkbook wb = WorkbookFactory.Create(readfile); number = wb.NumberOfSheets; } } return number; } /// <summary> /// 判断内容是否是数字 /// </summary> /// <param name="message"></param> /// <param name="result"></param> /// <returns></returns> public static bool isNumeric(String message, out double result) { Regex rex = new Regex(@"^[-]?\d+[.]?\d*$"); result = -1; if (rex.IsMatch(message)) { result = double.Parse(message); return true; } else return false; } /// <summary> /// 验证导入的Excel是否有数据 /// </summary> /// <param name="excelFileStream"></param> /// <returns></returns> public static bool HasData(Stream excelFileStream) { using (excelFileStream) { IWorkbook workBook = new HSSFWorkbook(excelFileStream); if (workBook.NumberOfSheets > 0) { ISheet sheet = workBook.GetSheetAt(0); return sheet.PhysicalNumberOfRows > 0; } } return false; } } /// <summary> /// 排序实现接口 不进行排序 根据添加顺序导出 /// </summary> public class NoSort : IComparer { public int Compare(object x, object y) { return -1; } }}

三、调用

3.1、增加一个“keywords”模型类,用作导出

public class keywords{ [Column("姓名")] public string IllegalKeywords { get; set; }}

3.2、添加一个控制器

3.3、编写导入导出的控制器代码

3.3.1、重写“Close”函数

在导出时,为了防止MemoryStream无法关闭从而报错,所以我们继承MemoryStream;代码如下:

namespace WebApplication1 //命名空间依据自己的项目进行修改{ public class NpoiMemoryStream : MemoryStream { public NpoiMemoryStream() { AllowClose = true; } public bool AllowClose { get; set; } public override void Close() { if (AllowClose) base.Close(); } }}

3.3.2、添加控制器代码

/// <summary>/// 本地环境/// </summary>private IHostingEnvironment _hostingEnv;/// <summary>/// Excel导入的具体实现/// </summary>/// <returns></returns>public IActionResult import_excel(){ string filepath = _hostingEnv.WebRootPath + "/在线用户20230324.xlsx";//导入的文件地址路径,可动态传入 Dictionary<string, string> dir = new Dictionary<string, string>();//申明excel列名和DataTable列名的对应字典 dir.Add("IllegalKeywords","姓名"); List<keywords> keyWordsList = ExcelHelper.ImportExceltoDt<keywords>(filepath, dir,"Sheet1",0); #region 将List动态添加至数据库 //…… #endregion return Json(new { code = 200, msg = "导入成功" });}/// <summary>/// Excel导出的具体实现/// </summary>/// <returns></returns>public IActionResult export_excel(){ #region 添加测试数据 List<keywords> keys = new List<keywords>(); for (int i = 0; i < 6; i++) { keywords keyword = new keywords(); keyword.IllegalKeywords = "测试_" + i; keys.Add(keyword); } #endregion #region 实例化DataTable并进行赋值 DataTable dt = new DataTable(); dt = listToDataTable(keys);//List<T>对象集合转DataTable #endregion string filename = DateTime.Now.ToString("在线用户yyyyMMdd") + ".xlsx"; Dictionary<string, string> dir = new Dictionary<string, string>(); dir.Add("IllegalKeywords", "姓名"); XSSFWorkbook book= ExcelHelper.ExportExcel(dt, dir); dt.Dispose();//释放DataTable所占用的数据资源 NpoiMemoryStream ms = new NpoiMemoryStream(); ms.AllowClose = false; book.Write(ms, true); ms.Flush(); ms.Position = 0; ms.Seek(0, SeekOrigin.Begin); ms.AllowClose = true; book.Dispose();//使用由XSSFWorkbook所占用的资源 return File(ms, "application/vnd.ms-excel", Path.GetFileName(filename));//进行浏览器下载}

3.3.3、Excel导出效果

3.3.4、Excel导入效果

以上就是如何用excel导出上市公司财务报表?的详细内容,希望通过阅读小编的文章之后能够有所收获!

版权:本文由用户自行上传,观点仅代表作者本人,本站仅供存储服务。如有侵权,请联系管理员删除,了解详情>>

发布
问题