zoukankan      html  css  js  c++  java
  • React+后端实现导出Excle表格的功能

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

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

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

    1.导出图标

    按钮代码:

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

    2.按钮this.excelToPort的方法:

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

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

    Excel Bean

     1 package com.test;
     2 
     3 import lombok.Getter;
     4 import lombok.Setter;
     5 import org.apache.poi.xssf.usermodel.XSSFCellStyle;
     6 
     7 @Getter
     8 @Setter
     9 public class ExcelBean {
    10     private String headTextName; //列头(标题)名
    11     private String propertyName; //对应字段名
    12     private Integer cols; //合并单元格数
    13     private XSSFCellStyle cellStyle;
    14 
    15     public ExcelBean(String headTextName, String propertyName, Integer cols) {
    16         super();
    17         this.headTextName = headTextName;
    18         this.propertyName = propertyName;
    19         this.cols = cols;
    20     }
    21 
    22 }

    映射到数据库里的User Bean

     1 package com.bqs.data.dcm.bean;
     2 
     3 import lombok.Getter;
     4 import lombok.Setter;
     5 
     6 @Getter
     7 @Setter
     8 public class User {
     9     private String id; 
    10     private String name; 
    11     private Integer age;
    12     private String sex;
    13     
    14 }

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

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

    5.导出Excel的controller类

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

    6.导出Excel的service类

     1   public XSSFWorkbook exportExcel() throws Exception{
     2         //获取dao导出的list集合
     3         List<User> list=userService.exportUser();
     4        
     5         List<Map<String,Object>> listMap=ListBeanToListMap(list);
     6 
     7         List<ExcelBean> excel = new ArrayList<>();
     8         Map<Integer,List<ExcelBean>> map = new LinkedHashMap<>();
     9         //设置标题栏
    10         excel.add(new ExcelBean("序号","id",0));
    11         excel.add(new ExcelBean("名字","name",0));
    12         excel.add(new ExcelBean("年龄","age",0));
    13         
    14            map.put(0,excel);
    15         String sheetName = "统计表格";
    16         //调用ExcelUtil方法
    17         XSSFWorkbook xssfWorkbook = ExportUtil.createExcelFile(DcmDemand.class, listMap, map, sheetName);
    18         System.out.println(xssfWorkbook);
    19         return xssfWorkbook;
    20     }            

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

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

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

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

     1  public static List<Map<String, Object>> ListBeanToListMap(List<User> list) throws NoSuchMethodException,
     2             SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
     3         List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
     4 
     5         for (Object ob : list) {
     6 
     7             listmap.add(beanToMap(ob));
     8         }
     9         return listmap;
    10     }

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

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

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/zhujiqian/p/11661435.html
Copyright © 2011-2022 走看看