最近在做一个基于React+antd前端框架的Excel导出功能,我主要在后端做了处理,这个功能完成后,便总结成一篇技术分享文章,感兴趣的小伙伴可以参考该分享来做导出excle表格功能,以下步骤同样适用于vue框架,或者JSP页面的实现。

在做这类导出文件的功能,其实,在后端进行处理,会更容易些,虽然前端也可以进行处理,但还是建议后端来做,因为很多导出工具类基本都是很好用。

根据以下步骤,可以很容易就实现导出Excel表格数据的功能。

1.导出图标

按钮代码:

 <Button type="primary" onClick={this.excelPort} >导出</Button>

2.按钮this.excelToPort的方法:

 excelPort = () => {
location.href="/test/export.do"
}

3.建立Excel的Entity类(以下类可以直接复制用,无需做修改):

Excel Bean

 package com.test;

 import lombok.Getter;
import lombok.Setter;
import org.apache.poi.xssf.usermodel.XSSFCellStyle; @Getter
@Setter
public class ExcelBean {
private String headTextName; //列头(标题)名
private String propertyName; //对应字段名
private Integer cols; //合并单元格数
private XSSFCellStyle cellStyle; public ExcelBean(String headTextName, String propertyName, Integer cols) {
super();
this.headTextName = headTextName;
this.propertyName = propertyName;
this.cols = cols;
} }

映射到数据库里的User Bean

 package com.bqs.data.dcm.bean;

 import lombok.Getter;
import lombok.Setter; @Getter
@Setter
public class User {
private String id;
private String name;
private Integer age;
private String sex; }

4.建立Excel的工具类(无需修改可直接复制用)

 package com.test;

 import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map; import com.test.ExcelBean;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; /**
* @author 朱季谦
* @version
*/
public class ExportUtil { /**
* 导出Excel表
* @param clazz 数据源model类型
* @param objs excel标题以及对应的model字段
* @param map 标题行数以及cell字体样式
* @param sheetName 工作簿名称
* @return
*
*/
public static XSSFWorkbook createExcelFile(
Class<?> clazz,
List<Map<String,Object>> objs,
Map<Integer,List<ExcelBean>> map,
String sheetName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException{
//创建新的工作簿
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表
XSSFSheet sheet = workbook.createSheet(sheetName);
//设置excel的字体样式以及标题与内容的创建
createFont(workbook);//字体样式
createTableHeader(sheet,map);//创建标题
createTableRows(sheet,map,objs,clazz);//创建内容
System.out.println(workbook);
return workbook;
}
private static XSSFCellStyle fontStyle;
private static XSSFCellStyle fontStyle2;
private static void createFont(XSSFWorkbook workbook) {
//表头
fontStyle = workbook.createCellStyle();
XSSFFont font1 = workbook.createFont();
font1.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
font1.setFontName("黑体");
font1.setFontHeightInPoints((short) 12);//字体大小
fontStyle.setFont(font1);
fontStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框
fontStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框
fontStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框
fontStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框
fontStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中
//内容
fontStyle2 = workbook.createCellStyle();
XSSFFont font2 = workbook.createFont();
font2.setFontName("宋体");
font2.setFontHeightInPoints((short)10);
fontStyle2.setFont(font2);
fontStyle2.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框
fontStyle2.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框
fontStyle2.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框
fontStyle2.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框
fontStyle2.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中
} /**
* 根据ExcelMapping 生成列头(多行列头)
* @param sheet 工作簿
* @param map 每行每个单元格对应的列头信息
*/
private static void createTableHeader(
XSSFSheet sheet,
Map<Integer, List<ExcelBean>> map) {
int startIndex = 0;//cell起始位置
int endIndex = 0;//cell终止位置
for(Map.Entry<Integer,List<ExcelBean>> entry: map.entrySet()){
XSSFRow row = sheet.createRow(entry.getKey()); //创建行
List<ExcelBean> excels = entry.getValue();
for(int x=0;x<excels.size();x++){
//合并单元格
if(excels.get(x).getCols()>1){
if(x==0){
endIndex += excels.get(x).getCols()-1;
//合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
startIndex += excels.get(x).getCols();
}else{
endIndex += excels.get(x).getCols();
sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
startIndex += excels.get(x).getCols();
}
XSSFCell cell = row.createCell(startIndex-excels.get(x).getCols());
//设置内容
cell.setCellValue(excels.get(x).getHeadTextName());
if(excels.get(x).getCellStyle() != null){
//设置格式
cell.setCellStyle(excels.get(x).getCellStyle());
}
cell.setCellStyle(fontStyle);
}else{
XSSFCell cell = row.createCell(x);
//设置内容
cell.setCellValue(excels.get(x).getHeadTextName());
if(excels.get(x).getCellStyle() != null){
//设置格式
cell.setCellStyle(excels.get(x).getCellStyle());
}
cell.setCellStyle(fontStyle);
}
}
}
} /**
* 为excel表中循环添加数据
* @param sheet
* @param map 字段名
* @param objs 查询的数据
* @param clazz 无用
*/
private static void createTableRows(
XSSFSheet sheet,
Map<Integer,List<ExcelBean>> map,
List<Map<String,Object>> objs,
Class<?> clazz)
throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
int rowindex = map.size();
int maxkey = 0;
List<ExcelBean> ems = new ArrayList<>();
for(Map.Entry<Integer,List<ExcelBean>> entry : map.entrySet()){
if(entry.getKey() > maxkey){
maxkey = entry.getKey();
}
}
ems = map.get(maxkey);
List<Integer> widths = new ArrayList<Integer>(ems.size());
for(Map<String,Object> obj : objs){
XSSFRow row = sheet.createRow(rowindex);
for(int i=0;i<ems.size();i++){
ExcelBean em = (ExcelBean)ems.get(i);
String propertyName = em.getPropertyName();
Object value = obj.get(propertyName);
XSSFCell cell = row.createCell(i);
String cellValue = "";
if("valid".equals(propertyName)){
cellValue = value.equals(1)?"启用":"禁用";
}else if(value==null){
cellValue = "";
}else if(value instanceof Date){
cellValue = new SimpleDateFormat("yyyy-MM-dd").format(value);
}else{
cellValue = value.toString();
}
cell.setCellValue(cellValue);
cell.setCellType(XSSFCell.CELL_TYPE_STRING);
cell.setCellStyle(fontStyle2);
sheet.autoSizeColumn(i);
}
rowindex++;
} //设置列宽
for(int index=0;index<widths.size();index++){
Integer width = widths.get(index);
width = width<2500?2500:width+300;
width = width>10000?10000+300:width+300;
sheet.setColumnWidth(index, width);
}
}
}

5.导出Excel的controller类

    /**
* 导出excle表格
*/
@RequestMapping(value = "/export")
public void exportTotal( HttpServletResponse response ) throws Exception{
response.reset(); //清除buffer缓存
//Map<String,Object> map=new HashMap<String,Object>();
// 指定下载的文件名
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
String excleName="统计表格"+".xlsx";
response.setHeader("Content-Disposition","attachment;filename="+new String(excleName.getBytes(),"iso-8859-1"));
//导出Excel对象
XSSFWorkbook workbook = sysExportExcelInfo.exportExcel();
OutputStream output;
try {
output = response.getOutputStream();
BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
bufferedOutput.flush();
workbook.write(bufferedOutput);
bufferedOutput.close(); } catch (IOException e) {
e.printStackTrace();
}
}

6.导出Excel的service类

   public XSSFWorkbook exportExcel() throws Exception{
//获取dao导出的list集合
List<User> list=userService.exportUser(); List<Map<String,Object>> listMap=ListBeanToListMap(list); List<ExcelBean> excel = new ArrayList<>();
Map<Integer,List<ExcelBean>> map = new LinkedHashMap<>();
//设置标题栏
excel.add(new ExcelBean("序号","id",0));
excel.add(new ExcelBean("名字","name",0));
excel.add(new ExcelBean("年龄","age",0)); map.put(0,excel);
String sheetName = "统计表格";
//调用ExcelUtil方法
XSSFWorkbook xssfWorkbook = ExportUtil.createExcelFile(DcmDemand.class, listMap, map, sheetName);
System.out.println(xssfWorkbook);
return xssfWorkbook;
}

注意:整块导出Excel代码,主要需要改动只是这一行代码:List<User> list=userService.exportUser(),这是调用dao层获取以列表list获得数据的查询。

下面三行代码里的“序号”,“名字”,“年龄”根据User属性来定义的,它将作为表格表头呈现在导出的表格里。这里的User表映射到数据库表t_user表,你需要导出User里哪些字段的数据,就以这样格式excel.add(new ExcelBean("序号","id",0))加到下面代码里:

 excel.add(new ExcelBean("序号","id",0));
excel.add(new ExcelBean("名字","name",0));
excel.add(new ExcelBean("年龄","age",0));

其中,以上代码需要把list<String>转换成List<Map<String,Object>>形式,转换方法如下,因为创建表格时需要这样List<Map<String,Object>>格式类型数据:

  public static List<Map<String, Object>> ListBeanToListMap(List<User> list) throws NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>(); for (Object ob : list) { listmap.add(beanToMap(ob));
}
return listmap;
}

按照以上代码步骤,可以实现在React+antd前端实现导出这样的Excel表格功能:

若有什么不明白的,可以评论留言,我会尽量解答。

React+后端实现导出Excle表格的功能的更多相关文章

  1. 4-13 Webpacker-React.js; 用React做一个下拉表格的功能: <详解>

    Rails5.1增加了Webpacker: Webpacker essentially is the decisions made by the Rails team and bundled up i ...

  2. 前端 vue/react 或者 js 导入/导出 xlsx/xls (带样式)表格的功能

    第一种导出表格的功能: yarn add xlsx script-loader file-saver xlsx-style 效果展示 xlsx-style的bug修复:node_module/xlsx ...

  3. 数据库数据怎样导出成Excle表格或Word文档?

    数据导出:将数据库的数据导出成Excel工作表或Word文档 方法:将一个泛型集合导出出去 主要使用: SaveFileDialog StreamWriter 导出代码: private void b ...

  4. EasyUi通过POI 实现导出xls表格功能

    Spring +EasyUi+Spring Jpa(持久层) EasyUi通过POI 实现导出xls表格功能 EasyUi界面: 点击导出按钮实现数据导入到xls表格中 第一步:修改按钮事件: @Co ...

  5. java导入excle表格,并且对表格进行相应的修改,并对表格数据进行整理,最后导出本地表格等一系列操作

    1.首先创建一个java项目 完成效果如下图所示 2.导入以下jar包 3.代码如下 其中行和列的操作是根据需求自动划分的 public class auto_date { private stati ...

  6. 一个php将数据库的数据导出到excle表格中的小dome

    首先我们需要下载个PHPExcel,PHPExcel下载地址链接:https://pan.baidu.com/s/1nxpAc45 密码:qgct 下面来写个dome: <?php //把数据写 ...

  7. Vue中导出Excel表格方法

    本文记录一下在Vue中实现导出Excel表格的做法.参考度娘上各篇博客,最后实现功能 Excel表格,我的后端返回的是数据流,然后文件名是放进了content-disposition中,前端进行获取. ...

  8. PHP导入导出excel表格图片(转)

    写excel的时候,我用过pear的库,也用过pack压包的头,同样那些利用smarty等作的简单替换xml的也用过,csv的就更不用谈了.呵呵.(COM方式不讲了,这种可读的太多了,我也写过利用wp ...

  9. php:PHPExcel导出excel表格

    一.动态生成的内容如何能当成文件来下载呢? 方法:1.将Content-Type设置成application/octet-stream就可以了,即[header('Content-Type: appl ...

随机推荐

  1. 微服务SpringCloud之配置中心和消息总线

    在微服务SpringCloud之Spring Cloud Config配置中心SVN博客中每个client刷新配置信息时需要post请求/actuator/refresh,但客户端越来越多时,,需要每 ...

  2. 《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性

    IM 系统中,保证消息的可靠投递主要体现在两方面,一是消息的不丢失,二是消息的不重复. 一.消息不丢失 消息丢失的原因 首先看一下发送消息的流程,如下图所示: 消息.可以采取"时间戳比对&q ...

  3. Day004_Linux基础_基础命令之tar打包解包

    基础命令之 打包,和解包. tar zcvf 打包的参数  tar zcvf /tmp/etc.tar.gz /etc  将/etc/下的文件压缩成一个压缩包 z  通过gzip工具进行压缩 c 表示 ...

  4. Appium+python自动化(三十六)- 士兵突击许三多 - 多个appium服务启动,多个设备启动,多进程并发启动设备-并发测试 - 上(超详解)

    简介 前面课程只是启动了单个appium服务,只能控制单台设备.如果需要针对多台设备测试那么该如何处理?而且发现群里的小伙伴们也在时不时地在讨论这个问题,想知道怎么实现的,于是宏哥就决定写一片这样的文 ...

  5. Java开学测试

    这次开学测试要求做一个信息系统,该系统完成学生成绩录入,修改,计算学分积点和查询学生成绩的简单功能. 下面是我写的代码 //信1805-3班 20183641 赵树琪 package test; im ...

  6. Go语言标准库之fmt

    fmt标准库是我们在学习Go语言过程中接触最早最频繁的一个了,本文介绍了fmtb包的一些常用函数. fmt fmt包实现了类似C语言printf和scanf的格式化I/O.主要分为向外输出内容和获取输 ...

  7. Navicate for mysql如何导入一个sql文件

    我在做的项目是宜立方商城的项目,现在需要把见表的sql文件导入到navicate中去,步骤如下: ①新建一个数据库,如下: ②在数据库名字上右键,选择运行sql文件 ③选择如下sql文件 ④刷新之后:

  8. JAVA代码解析String字符串(json格式的)

    java解析String字符串(json格式) 需要jar包:json-lib-2.4-jdk15.jar 一. String str = "{\"name\":\&qu ...

  9. SpringCloud超简单的入门(1)--一些简单的介绍

    简介 简单来说,springcloud的就是由一组springboot应用(服务)组成,相互之间通过REST等方式进行通信. 两个springboot应用,其中一个作为服务提供者,一个作为服务消费者, ...

  10. Spring Cloud同步场景分布式事务怎样做?试试Seata

    一.概述 在微服务架构下,虽然我们会尽量避免分布式事务,但是只要业务复杂的情况下这是一个绕不开的问题,如何保证业务数据一致性呢?本文主要介绍同步场景下使用Seata的AT模式来解决一致性问题. Sea ...