java自定义excel
文件下载
本文主要介绍spring boot环境下,利用Apache POI操作Excel,实现Excel文件的在线下载。
首先,我们在这里介绍一下关于ApachePOI中关于HSSF,XSSF和SXSSF的区别。
HSSF是POI工程对Excel 97(-2007)文件操作的纯Java实现,使用的 .xls 做结尾的文件
XSSF是POI工程对Excel 2007以后版本 (.xlsx)文件操作的纯Java实现,使用 .xlsx 做结尾的文件
从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的API----SXSSF
因为Excel版本的不断升级,就目前使用而言,一般使用较多的是XSSF,而网上大部分教程还停留在老版本(HSSF);SXSSF由于使用用户较少,还有不少不适用户使用习惯的坑未填,对用普通开发者来说较为复杂,所以只要不是对性能有较强要求的用户,不建议使用。接下来就主要介绍一下XSSF的使用:
- 首先根据需求创建模板文件,在模板文件中设置好要输出的列名(表头),注意要  和sql检索出来的列名一致

 - 上代码
 
@Override
public void reportsExcelPrint(HttpServletResponse response) {
List<Map<String,Object>> reportList = null;
String projectName="";
//检索数据库数据--用来赋值Excel
reportList = projectMapper.selByValue(projectName);
//模板文件路径
String modalUrl="template/项目周报.xlsx";
//sheet名称
String sheetName="项目周报";
// 对应数据库列名--和模板设置的列一致
String[] colKeys={"weekNumber","projectName"};
exportFile(reportList,colKeys,modalUrl,sheetName,response);
}
private void exportFile(List<Map<String, Object>> reportList, String[] colKeys, String modalUrl, String sheetName, HttpServletResponse response) {
    OutputStream out = null;
    try {
        Map<String, Object> results = new HashMap<>();
        results.put("talentFlows", "");
        // 拿到模板文件
        InputStream in = getClass().getClassLoader().getResourceAsStream(modalUrl);
        //新建workbook
        tpWorkbook = new XSSFWorkbook(in);
        //填入数据
        sheet = tpWorkbook.getSheet(sheetName);
        if (reportList != null) {
            //设置表格数据
            setCellData(reportList, colKeys);
        }
        //输出流
        out = response.getOutputStream();
        response.reset();
        response.setHeader("content-disposition",
                "attachment;filename=" + new String((sheetName).getBytes("gb2312"), "ISO8859-1") + ".xlsx");
        response.setContentType("APPLICATION/msexcel");
        //设置打印对象
        XSSFPrintSetup printSetup = sheet.getPrintSetup();
        //设置打印方向
        printSetup.setLandscape(true);
        // 新建一个Excel的工作空间
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 把模板复制到新建的Excel
        workbook = tpWorkbook;
        // 输出Excel内容,生成Excel文件
        workbook.write(out);
    } catch (final IOException e) {
        e.printStackTrace();
    } finally {
        try {
            // 关闭输出流
            response.flushBuffer();
            if (out != null) {
                out.flush();
                out.close();
            }
        } catch (final IOException e) {
        }
    }
}
/**
* 创建表体数据
* @param data - 表体数据
*/
private void setCellData(List<Map<String, Object>> data, String[] colKeys) {
  //创建表头
  createHeader();
  //创建合计项变量
  zq_hs = 0;
  int rowSize = 0;
  // 创建数据
  XSSFRow row = null;
  XSSFCell cell = null;
  int i = 3;//startRow:数据开始行
  if (data != null && data.size() > 0) {
      for (int m = 0; m < data.size(); m++) {
          row = sheet.createRow(i);
          if (i == 3) {//第一行
              rowSize = i;
              setCellValue(data, colKeys, row, cell, m);
          } else {
              if (data.get(m).get("blId") == data.get(m - 1).get("blId")) {//相同字段
                  setCellValue(data, colKeys, row, cell, m);
              } else {//合计行
                  if (rowSize != (i - 1)) {//多于1条数据时合并单元格
                      CellRangeAddress cra = new CellRangeAddress(rowSize, i - 1, 2, 2); // 起始行, 终止行, 起始列, 终止列
                      sheet.addMergedRegion(cra);
                      RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);// 下边框
                      RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet); // 右边框
                  }
                  //合计行
                  createTailCellWeekly1(i, zq_hs);
                  zq_hs = 0;
                  i = i + 1;
                  rowSize = i;
                  row = sheet.createRow(i);
                  //下一个模块
                  setCellValue(data, colKeys, row, cell, m);
              }
              //项目总合计
              if (m == (data.size() - 1)) {
                  if (rowSize != i) {//多于1条数据时合并单元格
                      CellRangeAddress cra = new CellRangeAddress(rowSize, i, 2, 2); // 起始行, 终止行, 起始列, 终止列
                      sheet.addMergedRegion(cra);
                      RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);// 下边框
                      RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet); // 右边框
                  }
                  zq_hsZ = zq_hsZ + zq_hs;
                  //合计行
                  i = i + 1;
                  createTailCellWeekly1(i, zq_hs);
              }
          }
          if (data.size() == 1) {
              //项目总计累加
              zq_hsZ = zq_hsZ + zq_hs;/
              i = i + 1;
              //合计行
              createTailCellWeekly1(i, zq_hs);
          }
          i++;//下一行
          //行赋值完成后,对当前行操作
          styleWeekly(row);
      }
  }
  //创建表尾
  createTailCellWeekly2(i - 1, zq_hsZ, zq_mjZ, hd_hsZ, hd_hs_dzwcZ, hd_mjZ, hd_mj_dzwcZ, azf_rwZ, azf_ykgZ, gd_rwZ, gd_ywc_weekZ);
}
//创建表头
private void createHeader(String year) {
    // 创建数据
    XSSFCell cell = null;
    XSSFRow row0 = sheet.getRow(0);
    row0.getCell(0).setCellValue(year + "项目计划表");
    XSSFRow row1 = sheet.getRow(1);
    cell = row1.getCell(10);
    cell.setCellValue(year + "项目投资");
    cell = row1.getCell(16);
    cell.setCellValue(year + "项目oo");
}
/**
 * @return void
 * @Description //TODO 行赋值
 * @Param [data, colKeys, backupType, row, cell, m]
 */
private void setCellValue(List<Map<String, Object>> data, String[] colKeys XSSFRow row, XSSFCell cell, int m) {
    XSSFCellStyle cellStyleTongJi = tpWorkbook.createCellStyle();
    XSSFFont font = tpWorkbook.createFont();
    font.setFontHeightInPoints((short) 36);// 字体大小
    cellStyleTongJi.setFont(font);
    cellStyleTongJi.setBorderBottom(BorderStyle.THIN); // 下边框
    cellStyleTongJi.setBorderRight(BorderStyle.THIN);// 右边框
    cellStyleTongJi.setBorderLeft(BorderStyle.THIN);//下边框
    cellStyleTongJi.setAlignment(HorizontalAlignment.CENTER_SELECTION);//水平对齐
    cellStyleTongJi.setVerticalAlignment(VerticalAlignment.CENTER);//上下对齐
    cellStyleTongJi.setWrapText(true);//自动换行
    XSSFCellStyle cellStyleTongJi1 = tpWorkbook.createCellStyle();
    cellStyleTongJi1.setFont(font);
    cellStyleTongJi1.setBorderBottom(BorderStyle.THIN); // 下边框
    cellStyleTongJi1.setBorderRight(BorderStyle.THIN);// 右边框
    cellStyleTongJi1.setAlignment(HorizontalAlignment.LEFT);//水平对齐
    cellStyleTongJi1.setVerticalAlignment(VerticalAlignment.CENTER);//上下对齐
    cellStyleTongJi1.setWrapText(true);//自动换行
    int j = 0;
    for (String key : colKeys) {
        Object colValue = data.get(m).get(key);
        cell = row.createCell(j);
        //后2列文字描述左对齐
        if (key.equalsIgnoreCase("col1") || key.equalsIgnoreCase("col2")) {
            cell.setCellStyle(cellStyleTongJi1);
        } else {
            cell.setCellStyle(cellStyleTongJi);
        }
        if (colValue != null) {
            //单元格赋值
            if (key.equalsIgnoreCase("col3")) {
                cell.setCellValue(colValue.toString() + "地区");
            } else if (key.equalsIgnoreCase("col4")) {
                cell.setCellValue(new BigDecimal(colValue.toString()).stripTrailingZeros().toPlainString());//BigDecimal=>number
            } else if (key.equalsIgnoreCase("col5") || key.equalsIgnoreCase("col6") || ) {
                cell.setCellValue(new BigDecimal(colValue.toString()).stripTrailingZeros().toPlainString());//BigDecimal=>number
            } else {
                cell.setCellValue(colValue.toString());
            }
            //计算合计值
            switch (key) {
                case "planMoveCount":
                    zq_hs += Double.parseDouble(String.valueOf(colValue));
                    break;
                case "planMoveArea":
                    zq_mj += Double.parseDouble(String.valueOf(colValue));
                    break;
                case "mYearCount":
                    hd_hs += Double.parseDouble(String.valueOf(colValue));
                    break;
                case "mWeekCount":
                    hd_hs_dzwc += Double.parseDouble(String.valueOf(colValue));
                    break;
            }
        } else {
            cell.setCellValue("--");
        }
        j++;
    }
}
/**
 * @return void
 * @Description //TODO 创建合计项
 * @Param [size, zq_hs]
 */
private void createTailCellWeekly1(int size, double zq_hs) {
    XSSFCellStyle cellStyleTongJi = tpWorkbook.createCellStyle();
    XSSFFont font = tpWorkbook.createFont();
    font.setBold(true);
    font.setFontHeightInPoints((short) 36);// 字体大小
    cellStyleTongJi.setFont(font);
    cellStyleTongJi.setBorderBottom(BorderStyle.THIN); // 下边框
    cellStyleTongJi.setBorderRight(BorderStyle.THIN);// 右边框
    cellStyleTongJi.setBorderLeft(BorderStyle.THIN);//下边框
    cellStyleTongJi.setAlignment(HorizontalAlignment.CENTER_SELECTION);//水平对齐
    cellStyleTongJi.setVerticalAlignment(VerticalAlignment.CENTER);//上下对齐
    cellStyleTongJi.setWrapText(true);//自动换行
    //合计
    XSSFRow rowTail1 = sheet.createRow(size);
    rowTail1.setHeightInPoints((short) 100);
    sheet.addMergedRegion(new CellRangeAddress(size, size, 0, 2));
    XSSFCell cellTail1 = rowTail1.createCell(0);
    cellTail1.setCellValue("合计");
    cellTail1.setCellStyle(cellStyleTongJi);
    XSSFCell cellTail102 = rowTail1.createCell(1);
    cellTail102.setCellValue("");
    cellTail102.setCellStyle(cellStyleTongJi);
    XSSFCell cellTail103 = rowTail1.createCell(2);
    cellTail103.setCellValue(zq_hs);
    cellTail103.setCellStyle(cellStyleTongJi);
}
/**
 * @return void
 * @Description //TODO 导出完成后格式整理
 * @Param [row]
 */
private void styleWeekly(XSSFRow row){
    for(int k=16;k< 17;k++){
        sheet.autoSizeColumn(k,true);//自适应列宽
        if(row.getCell(k).toString()=="--"){
            row.getCell(k).setCellValue("");
        }
    }
    if(row.getCell(9).toString()!="--"){
        if(row.getCell(3).toString()=="--"){
            row.getCell(3).setCellValue(0);
        }
    }else{
        if(row.getCell(3).toString()=="--"){
            row.getCell(3).setCellValue("--");
        }
    }
}
												
											java自定义excel的更多相关文章
- Java 自定义Excel数据排序
		
通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值.单元格颜色.字体颜色或图标等.在需要自定义排序情况下,我们也可以自行根据排序需要编辑数据排列顺序.本文,将通过 ...
 - Java读写Excel之POI超入门
		
转自:http://rensanning.iteye.com/blog/1538591 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给J ...
 - Java读写Excel之POI超入门(转)
		
Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.Apache POI ...
 - Java实现Excel数据批量导入数据库
		
Java实现Excel数据批量导入数据库 概述: 这个小工具类是工作中的一个小插曲哦,因为提数的时候需要跨数据库导数... 有的是需要从oracle导入mysql ,有的是从mysql导入oracle ...
 - JAVA生成EXCEL模板
		
JAVA生成excel模板,支持1.必填字段前加 红色 * 2.定义可选值下拉列表 valList3.定义名称并通过名称设置可选值 refName(名称在sheet2,sheet2自动隐藏)4.支持设 ...
 - java操作excel 工具类
		
java操作excel 可参考https://blog.csdn.net/xunwei0303/article/details/53213130 直接上代码: 一.java生成excel文件: pac ...
 - java自定义注解类
		
一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...
 - java程序转换excel中科学记数法的数据为date类型
		
今天出于某些原因从mongodb数据库中导出了一些数据,为了更直观的发送给其他人查阅,便使用mongoVUE的导出为excel功能. 但是导出后出现了一个问题,里边有一列存储时间的,存储的是lon ...
 - java写入excel文件poi
		
java写入excel文件 java写入excel文件poi,支持xlsx与xls,没有文件自动创建 package com.utils; import java.io.File; import ja ...
 
随机推荐
- 关于Math.random()
			
关于 Math.random() ,以前经常搞混淆,这次写个笔记专门记录下: Math.random() : 返回的是 0~1 之间的一个随机小数0<=r<1,即[0,1); 注意:这里 ...
 - 常用css模板
			
段落超出显示省略号(可单行多行) .p-content{ overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-b ...
 - Beta冲刺(1/4)
			
队名:福大帮 组长博客链接: https://www.cnblogs.com/mhq-mhq/p/11990568.html 作业博客 : https://edu.cnblogs.com/campus ...
 - QT 多线程程序设计 -互斥
			
QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...
 - RoP
			
RoPS特征提取 RoPS为Rotational Projection Statistics的简写,即旋转投影统计特征.RoPS特征具有对点云旋转和平移(即姿态变化)的不变性,具备很强的鉴别力以及对噪 ...
 - 【论文学习】A Fuzzy-Rule-Based Approach for Single Frame Super Resolution
			
加尔各答印度统计研究所,作者: Pulak Purkait (pulak_r@isical.ac.in) 2013 年 代码:CodeForge.cn http://www.codeforge.cn/ ...
 - Nginx优化之日志优化,URL访问控制,防盗链,及站点文件目录优化
			
Nginx日志相关优化与安全 日志切割脚本如下: #!/bin #日志切割脚本 Date=`date +%Y%m%d` Bdir="/usr/local/nginx" Nginxl ...
 - WPF学习笔记 - 如何用WPF创建单实例应用程序
			
使用一个已命名的(操作系统范围的)互斥量. bool mutexIsNew; using(System.Threading.Mutex m = new System.Threading.Mulex(t ...
 - 一百零二:CMS系统之sweetalert提示框和使用
			
实现效果 css body.stop-scrolling { height: 100%; overflow: hidden; } .sweet-overlay { background-color: ...
 - Python的一个bug,记录一下
			
安装报错:E:\webpy-master>python setup.py installTraceback (most recent call last): File "setup.p ...