React+后端实现导出Excle表格的功能

简介: React+后端实现导出Excle表格的功能

原创/朱季谦


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

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

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

 

1.导出图标

按钮代码:

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

 

2.按钮this.excelToPort的方法:

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

 

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

Excel Bean

packagecom.test;
importlombok.Getter;
importlombok.Setter;
importorg.apache.poi.xssf.usermodel.XSSFCellStyle;
@Getter@SetterpublicclassExcelBean {
privateStringheadTextName; //列头(标题)名privateStringpropertyName; //对应字段名privateIntegercols; //合并单元格数privateXSSFCellStylecellStyle;
publicExcelBean(StringheadTextName, StringpropertyName, Integercols) {
super();
this.headTextName=headTextName;
this.propertyName=propertyName;
this.cols=cols;
     }
 }

映射到数据库里的User Bean

packagecom.bqs.data.dcm.bean;
importlombok.Getter;
importlombok.Setter;
@Getter@SetterpublicclassUser {
privateStringid; 
privateStringname; 
privateIntegerage;
privateStringsex;
 }

 

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

1packagecom.test;
23importjava.beans.IntrospectionException;
4importjava.lang.reflect.InvocationTargetException;
5importjava.text.SimpleDateFormat;
6importjava.util.ArrayList;
7importjava.util.Date;
8importjava.util.List;
9importjava.util.Map;
1011importcom.test.ExcelBean;
12importorg.apache.poi.ss.util.CellRangeAddress;
13importorg.apache.poi.xssf.usermodel.XSSFCell;
14importorg.apache.poi.xssf.usermodel.XSSFCellStyle;
15importorg.apache.poi.xssf.usermodel.XSSFFont;
16importorg.apache.poi.xssf.usermodel.XSSFRow;
17importorg.apache.poi.xssf.usermodel.XSSFSheet;
18importorg.apache.poi.xssf.usermodel.XSSFWorkbook;
1920/** 21  * @author 朱季谦 22  * @version 23  */24publicclassExportUtil {
2526/** 27      * 导出Excel表 28      * @param clazz 数据源model类型 29      * @param objs excel标题以及对应的model字段 30      * @param map 标题行数以及cell字体样式 31      * @param sheetName 工作簿名称 32      * @return 33      * 34      */35publicstaticXSSFWorkbookcreateExcelFile(
36Class<?>clazz,
37List<Map<String,Object>>objs,
38Map<Integer,List<ExcelBean>>map,
39StringsheetName) throwsIllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException{
40//创建新的工作簿41XSSFWorkbookworkbook=newXSSFWorkbook();
42//创建工作表43XSSFSheetsheet=workbook.createSheet(sheetName);
44//设置excel的字体样式以及标题与内容的创建45createFont(workbook);//字体样式46createTableHeader(sheet,map);//创建标题47createTableRows(sheet,map,objs,clazz);//创建内容48System.out.println(workbook);
49returnworkbook;
50     }
51privatestaticXSSFCellStylefontStyle;
52privatestaticXSSFCellStylefontStyle2;
53privatestaticvoidcreateFont(XSSFWorkbookworkbook) {
54//表头55fontStyle=workbook.createCellStyle();
56XSSFFontfont1=workbook.createFont();
57font1.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
58font1.setFontName("黑体");
59font1.setFontHeightInPoints((short) 12);//字体大小60fontStyle.setFont(font1);
61fontStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框62fontStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框63fontStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框64fontStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框65fontStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中66//内容67fontStyle2=workbook.createCellStyle();
68XSSFFontfont2=workbook.createFont();
69font2.setFontName("宋体");
70font2.setFontHeightInPoints((short)10);
71fontStyle2.setFont(font2);
72fontStyle2.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框73fontStyle2.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框74fontStyle2.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框75fontStyle2.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框76fontStyle2.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中77     }
78798081/** 82      * 根据ExcelMapping 生成列头(多行列头) 83      * @param sheet 工作簿 84      * @param map 每行每个单元格对应的列头信息 85      */86privatestaticvoidcreateTableHeader(
87XSSFSheetsheet,
88Map<Integer, List<ExcelBean>>map) {
89intstartIndex=0;//cell起始位置90intendIndex=0;//cell终止位置91for(Map.Entry<Integer,List<ExcelBean>>entry: map.entrySet()){
92XSSFRowrow=sheet.createRow(entry.getKey()); //创建行93List<ExcelBean>excels=entry.getValue();
94for(intx=0;x<excels.size();x++){
95//合并单元格96if(excels.get(x).getCols()>1){
97if(x==0){
98endIndex+=excels.get(x).getCols()-1;
99//合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列100sheet.addMergedRegion(newCellRangeAddress(0, 0, startIndex, endIndex));
101startIndex+=excels.get(x).getCols();
102                     }else{
103endIndex+=excels.get(x).getCols();
104sheet.addMergedRegion(newCellRangeAddress(0, 0, startIndex, endIndex));
105startIndex+=excels.get(x).getCols();
106                     }
107XSSFCellcell=row.createCell(startIndex-excels.get(x).getCols());
108//设置内容109cell.setCellValue(excels.get(x).getHeadTextName());
110if(excels.get(x).getCellStyle() !=null){
111//设置格式112cell.setCellStyle(excels.get(x).getCellStyle());
113                     }
114cell.setCellStyle(fontStyle);
115                 }else{
116XSSFCellcell=row.createCell(x);
117//设置内容118cell.setCellValue(excels.get(x).getHeadTextName());
119if(excels.get(x).getCellStyle() !=null){
120//设置格式121cell.setCellStyle(excels.get(x).getCellStyle());
122                     }
123cell.setCellStyle(fontStyle);
124                 }
125             }
126         }
127     }
128129130/**131      * 为excel表中循环添加数据132      * @param sheet133      * @param map  字段名134      * @param objs 查询的数据135      * @param clazz 无用136      */137privatestaticvoidcreateTableRows(
138XSSFSheetsheet,
139Map<Integer,List<ExcelBean>>map,
140List<Map<String,Object>>objs,
141Class<?>clazz)
142throwsIntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
143introwindex=map.size();
144intmaxkey=0;
145List<ExcelBean>ems=newArrayList<>();
146for(Map.Entry<Integer,List<ExcelBean>>entry : map.entrySet()){
147if(entry.getKey() >maxkey){
148maxkey=entry.getKey();
149             }
150         }
151ems=map.get(maxkey);
152List<Integer>widths=newArrayList<Integer>(ems.size());
153for(Map<String,Object>obj : objs){
154XSSFRowrow=sheet.createRow(rowindex);
155for(inti=0;i<ems.size();i++){
156ExcelBeanem= (ExcelBean)ems.get(i);
157StringpropertyName=em.getPropertyName();
158Objectvalue=obj.get(propertyName);
159XSSFCellcell=row.createCell(i);
160StringcellValue="";
161if("valid".equals(propertyName)){
162cellValue=value.equals(1)?"启用":"禁用";
163                 }elseif(value==null){
164cellValue="";
165                 }elseif(valueinstanceofDate){
166cellValue=newSimpleDateFormat("yyyy-MM-dd").format(value);
167                 }else{
168cellValue=value.toString();
169                 }
170cell.setCellValue(cellValue);
171cell.setCellType(XSSFCell.CELL_TYPE_STRING);
172cell.setCellStyle(fontStyle2);
173sheet.autoSizeColumn(i);
174             }
175rowindex++;
176         }
177178//设置列宽179for(intindex=0;index<widths.size();index++){
180Integerwidth=widths.get(index);
181width=width<2500?2500:width+300;
182width=width>10000?10000+300:width+300;
183sheet.setColumnWidth(index, width);
184         }
185     }
186 }

 

5.导出Excel的controller类

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

 

6.导出Excel的service类

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

     

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

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

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

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

publicstaticList<Map<String, Object>>ListBeanToListMap(List<User>list) throwsNoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<Map<String, Object>>listmap=newArrayList<Map<String, Object>>();
for (Objectob : list) {
listmap.add(beanToMap(ob));
          }
returnlistmap;
     }

 

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

 

 

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

 

目录
相关文章
|
8天前
|
前端开发 UED 开发者
React 数据表格分页实现
本文详细介绍了如何在React中实现数据表格的分页功能,包括基础实现、常见问题及解决方案。通过状态管理和事件处理,我们可以有效地减少页面加载时间,提升用户体验。文章提供了完整的代码示例,帮助开发者解决分页按钮样式、按钮过多和初始加载慢等问题,并给出了相应的优化方案。
83 53
|
26天前
|
移动开发 前端开发 JavaScript
React DnD:实现拖拽功能的终极方案?
本文首发于微信公众号“前端徐徐”,介绍了一个强大的 React 拖拽库——React DnD。React DnD 帮助开发者轻松创建复杂的拖拽界面,适用于 Trello 风格的应用、列表重排序、可拖拽的 UI 组件等场景。文章详细介绍了 React DnD 的基本信息、主要特点、使用场景及快速上手指南。
65 3
React DnD:实现拖拽功能的终极方案?
|
10天前
|
前端开发 UED 开发者
React 表格组件设计
本文介绍了 React 表格组件的设计,涵盖基本表格、虚拟滚动表格、可编辑表格和响应式表格。详细探讨了常见问题、易错点及解决方法,并提供了代码示例,帮助开发者提升表格组件的性能和用户体验。
29 5
|
9天前
|
前端开发 搜索推荐 测试技术
React 数据表格排序与过滤
本文介绍了如何在 React 中实现数据表格的排序和过滤功能,从基础概念到实际代码实现,涵盖排序和过滤的基本原理、实现步骤、常见问题及解决方法。通过合理管理状态、优化性能和避免常见错误,帮助开发者提高用户体验和开发效率。
25 4
|
2月前
|
移动开发 前端开发
react项目配合diff实现文件对比差异功能
在React项目中,可以使用`diff`库实现文件内容对比差异功能。首先安装`diff`库,然后在组件中引入并使用`Diff.diffChars`或`Diff.diffLines`方法比较文本差异。通过循环遍历`diff`结果,可以生成不同样式的HTML元素来高亮显示文本差异。
115 1
react项目配合diff实现文件对比差异功能
|
2月前
|
前端开发
React 中购物车功能实现(全选多选功能实现)
React 中购物车功能实现(全选多选功能实现)
37 2
|
1月前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
235 0
|
2月前
|
存储 移动开发 前端开发
初探react,用react实现一个todoList功能
该文章通过创建一个TodoList应用来介绍React的基础知识,包括环境搭建、组件创建、状态管理和事件处理,并演示了如何使用React Hooks来优化组件逻辑。
|
3月前
|
前端开发
|
3月前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
79 0

热门文章

最新文章