Java根据模板导出Excel报表并复制模板生成多个Sheet页

因为最近用报表导出比较多,所有就提成了一个工具类,本工具类使用的场景为  根据提供的模板来导出Excel报表

并且可根据提供的模板Sheet页进行复制 从而实现多个Sheet页的需求,

使用本工具类时,如果需求是每个Sheet页中的数据都不一致,但是表格样式和模板都一样

那么只需要在实际情况中根据 sql 来查询要添加的数据源 (只需更改数据源即可)

采用的技术为 POI 导出,因为类的缘故,目前只支持2003版本的Excel.

使用前请先下载相应jar包!

后期有时间的话会进行进一步完善,初次写工具类,若有不完善的地方还请包涵!

先看看模板样式和运行结果,然后直接上代码

这是Excel的模板样式

这是导出结果

具体实现看demo

package com.sgcc.xyz.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import com.sgcc.uap.persistence.impl.HibernateDaoImpl;
/**
 * 报表导出工具类
 *
 * @author JYLiu
 @巴黎的雨季
 本工具是根据POI对Excel2003进行报表导出 本工具类可根据模板进行Excel的导出
 *  并且可根据提供的模板Sheet页进行复制 从而实现多个Sheet页的需求
 *  使用本工具类时,如果需求是每个Sheet页中的数据都不一致,但是表格样式和模板都一样
 *  那么只需要在实际情况中根据 sql 来查询要添加的数据源 (只需更改数据源即可)
 */
public class ExcelUtil {
 /**
  * 根据模板导出报表,可导出多个Sheet页
  *
  * @param 导出的Excel文件名
  * @param 模板路径 (全路径)
  * @param 数据源
  * @param 返回请求
  * @param 生成的Sheet页的名称集合
  * @param 数据源中Map集合的key值 (key值对应的value值顺序要列名顺序一致)
  * @param 开始 循环写入数据 的行数(从第几行开始写入数据)
  */
 public static void ExcelByModel(String ExcelName, String ModelURl, List<Map<String, String>> dataSource,
   HttpServletResponse response, String[] sheetNames, String[] keyNames, int rowNum) throws Exception {
  // 设置导出Excel报表的导出形式
  response.setContentType("application/vnd.ms-excel");
  // 设置导出Excel报表的响应文件名
  String fileName = new String(ExcelName.getBytes("utf-8"), "ISO-8859-1");
  response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
  // 创建一个输出流
  OutputStream fileOut = response.getOutputStream();
  // 读取模板文件路径
  File file = new File(ModelURl);
  FileInputStream fins = new FileInputStream(file);
  POIFSFileSystem fs = new POIFSFileSystem(fins);
  // 读取Excel模板
  HSSFWorkbook wb = new HSSFWorkbook(fs);
  // 设置边框样式
  HSSFCellStyle style = wb.createCellStyle();
  style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  style.setBorderRight(HSSFCellStyle.BORDER_THIN);
  style.setBorderTop(HSSFCellStyle.BORDER_THIN);
  // 设置边框样式的颜色
  style.setBottomBorderColor(HSSFColor.BLACK.index);
  style.setLeftBorderColor(HSSFColor.BLACK.index);
  style.setRightBorderColor(HSSFColor.BLACK.index);
  style.setTopBorderColor(HSSFColor.BLACK.index);
  // 模板页
  HSSFSheet sheetModel = null;
  // 新建的Sheet页
  HSSFSheet newSheet = null;
  // 创建行
  HSSFRow row = null;
  // 创建列
  HSSFCell cell = null;
  // 循环建立Sheet页
  for (int i = 0; i < sheetNames.length; i++) {
   // 读取模板中模板Sheet页中的内容
   sheetModel = wb.getSheetAt(0);
   // 设置新建Sheet的页名
   newSheet = wb.createSheet(sheetNames[i]);
   // 将模板中的内容复制到新建的Sheet页中
   copySheet(wb, sheetModel, newSheet, sheetModel.getFirstRowNum(), sheetModel.getLastRowNum());
   //获取到新建Sheet页中的第一行为其中的列赋值
   row=newSheet.getRow(0);
   row.getCell(1).setCellValue("这是为表代码赋的值");
   //注意 合并的单元格也要按照合并前的格数来算
   row.getCell(6).setCellValue("这是为外部代码赋的值");
   //获取模板中的第二列,并赋值
   row=newSheet.getRow(1);
   row.getCell(1).setCellValue("表名称赋值");
   //注意 合并的单元格也要按照合并前的格数来算
   row.getCell(6).setCellValue("这是为是否系统表赋的值");
   // 遍历数据源 开始写入数据(因为Excel中是从0开始,所以减一)
   int num = rowNum - 1;
   for (Map<String, String> item : dataSource) {
    // 循环遍历,新建行
    row = newSheet.createRow((short) num);
    //判断有多少列数据
    for (int j = 0; j < keyNames.length; j++) {
     // 设置每列的数据   设置每列的样式   设置每列的值
     cell = row.createCell(j); cell.setCellStyle(style); cell.setCellValue(item.get(keyNames[j]));
    }
    num++;
   }
   // break 加break可以测试只添加一个Sheet页的情况
  }
  // 写入流
  wb.write(fileOut);
  // 关闭流
  fileOut.close();
 }
 /**
  *
  * @param Excel工作簿对象
  * @param 模板Sheet页
  * @param 新建Sheet页
  * @param 模板页的第一行
  * @param 模板页的最后一行
  */
 private static void copySheet(HSSFWorkbook wb, HSSFSheet fromsheet, HSSFSheet newSheet, int firstrow, int lasttrow) {
  // 复制一个单元格样式到新建单元格
  if ((firstrow == -1) || (lasttrow == -1) || lasttrow < firstrow) {
   return;
  }
  // 复制合并的单元格
  Region region = null;
  for (int i = 0; i < fromsheet.getNumMergedRegions(); i++) {
   region = fromsheet.getMergedRegionAt(i);
   if ((region.getRowFrom() >= firstrow) && (region.getRowTo() <= lasttrow)) {
    newSheet.addMergedRegion(region);
   }
  }
  HSSFRow fromRow = null;
  HSSFRow newRow = null;
  HSSFCell newCell = null;
  HSSFCell fromCell = null;
  // 设置列宽
  for (int i = firstrow; i < lasttrow; i++) {
   fromRow = fromsheet.getRow(i);
   if (fromRow != null) {
    for (int j = fromRow.getLastCellNum(); j >= fromRow.getFirstCellNum(); j--) {
     int colnum = fromsheet.getColumnWidth((short) j);
     if (colnum > 100) {
      newSheet.setColumnWidth((short) j, (short) colnum);
     }
     if (colnum == 0) {
      newSheet.setColumnHidden((short) j, true);
     } else {
      newSheet.setColumnHidden((short) j, false);
     }
    }
    break;
   }
  }
  // 复制行并填充数据
  for (int i = 0; i < lasttrow; i++) {
   fromRow = fromsheet.getRow(i);
   if (fromRow == null) {
    continue;
   }
   newRow = newSheet.createRow(i - firstrow);
   newRow.setHeight(fromRow.getHeight());
   for (int j = fromRow.getFirstCellNum(); j < fromRow.getPhysicalNumberOfCells(); j++) {
    fromCell = fromRow.getCell((short) j);
    if (fromCell == null) {
     continue;
    }
    newCell = newRow.createCell((short) j);
    newCell.setCellStyle(fromCell.getCellStyle());
    int cType = fromCell.getCellType();
    newCell.setCellType(cType);
    switch (cType) {
     case HSSFCell.CELL_TYPE_STRING:
      newCell.setCellValue(fromCell.getRichStringCellValue());
      break;
     case HSSFCell.CELL_TYPE_NUMERIC:
      newCell.setCellValue(fromCell.getNumericCellValue());
      break;
     case HSSFCell.CELL_TYPE_FORMULA:
      newCell.setCellValue(fromCell.getCellFormula());
      break;
     case HSSFCell.CELL_TYPE_BOOLEAN:
      newCell.setCellValue(fromCell.getBooleanCellValue());
      break;
     case HSSFCell.CELL_TYPE_ERROR:
      newCell.setCellValue(fromCell.getErrorCellValue());
      break;
     default:
      newCell.setCellValue(fromCell.getRichStringCellValue());
      break;
    }
   }
  }
 }
}

以上便是整个工具类的核心代码了

测试数据如下

/**
  * 测试多Sheet页导出数据表格方法
  */
 public static void ExcelTest(HttpServletResponse response){
  //构建数据源
  List<Map<String, String>> dataSourceList=new ArrayList<Map<String,String>>(){
   {
    add(new HashMap<String, String>(){{
     put("字段编号", "1");
     put("字段代码", "BUSINESS_ID");
     put("字段含义", "业务id");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", "是");
     put("主码", "");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "2");
     put("字段代码", "PROC_INST_ID");
     put("字段含义", "流程实例编号");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", "");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "3");
     put("字段代码", "PROC_STATE");
     put("字段含义", "流程状态");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "4");
     put("字段代码", "APPLICANT");
     put("字段含义", "申请人");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "5");
     put("字段代码", "LEAVE_TYPE");
     put("字段含义", "请假类型");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "6");
     put("字段代码", "REASON");
     put("字段含义", "请假事因");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "7");
     put("字段代码", "BEGIN_TIME");
     put("字段含义", "起始时间");
     put("数据类型", "TIMESTAMP");
     put("长度", "");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "8");
     put("字段代码", "END_TIME");
     put("字段含义", "结束时间");
     put("数据类型", "TIMESTAMP");
     put("长度", "");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "9");
     put("字段代码", "INSERT_PERSON");
     put("字段含义", "登记人");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
    add(new HashMap<String, String>(){{
     put("字段编号", "10");
     put("字段代码", "APPROVEDBY");
     put("字段含义", "批准人");
     put("数据类型", "VARCHAR");
     put("长度", "64");
     put("主键", " ");
     put("主码", " ");
    }});
   }
  };
  //构建数据源中的key值
  String[] keysStrings={"字段编号","字段代码","字段含义","数据类型","长度","主键","主码"};
  //每页的名称
  String [] sheetNameStrings={"Sheet1","Sheet2","Sheet3","Sheet4","Sheet5","Sheet6"};
  String modelURLString="D:\\model\\model.xls";
  try {
   ExcelUtil.ExcelByModel("测试模板导出", modelURLString, dataSourceList, response, sheetNameStrings, keysStrings, 6);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

以上就是关于Excel报表根据模板导出并生成多个Sheet也的小工具了,需要的可以参考代码,根据实际业务需求进行代码调整。

希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • java实现的导出Excel工具类实例

    本文实例讲述了java实现的导出Excel工具类.分享给大家供大家参考,具体如下: ExcelExportUtil: package com.excel; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.

  • Java使用excel工具类导出对象功能示例

    本文实例讲述了Java使用excel工具类导出对象功能.分享给大家供大家参考,具体如下: package com.gcloud.common; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.streaming.SXSSFSheet; import

  • Java数据导出功能之导出Excel文件实例

    在编程中经常需要使用到表格(报表)的处理主要以Excel表格为主.下面给出用java写入数据到excel表格方法: 1.添加jar文件 java导入导出Excel文件要引入jxl.jar包,最关键的是这套API是纯Java的,并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件.下载地址:http://www.andykhan.com/jexcelapi/ 2.jxl对Excel表格的认识 可以参见:http://www.jb51.net/article/686

  • JavaWeb导出Excel文件并弹出下载框

    一.引言 在Java Web开发中经常涉及到报表,最近做的项目中需要实现将数据库中的数据显示为表格,并且实现导出为Excel文件的功能. 二.相关jar包 使用POI可以很好的解决Excel的导入和导出的问题,POI下载地址: poi-3.6-20091214.jar 三.关键代码 首先导入上述jar包. 在生成excel时一般数据源形式为一个List,下面把生成Excel格式的代码贴出来: /** * 以下为生成Excel操作 */ // 1.创建一个workbook,对应一个Excel文件

  • java导出数据库的全部表到excel

    本文实例为大家分享了java将某个数据库的表全部导出到excel中的方法,供大家参考,具体内容如下 第一步:如何用POI操作Excel @Test public void createXls() throws Exception{ //声明一个工作薄 HSSFWorkbook wb = new HSSFWorkbook(); //声明表 HSSFSheet sheet = wb.createSheet("第一个表"); //声明行 HSSFRow row = sheet.createR

  • 在java poi导入Excel通用工具类示例详解

    前言 本文主要给大家介绍了关于java poi导入Excel通用工具类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 问题引入和分析 提示:如果不想看罗嗦的文章,可以直接到最后点击源码下载运行即可 最近在做一个导入Excel的功能,在做之前在百度上面查找"java通用导入Excel工具类",没有查到,大多数都是java通用导出Excel.后来仔细想想,导出可以利用java的反射,做成通用的,放进相应的实体成员变量中,导入为什么不可以呢?也是可以的,不过在做

  • JavaWeb中导出excel文件的简单方法

    在平时做系统项目时,经常会需要做导出功能,不论是导出excel,还是导出cvs文件.我下面的demo是在springmvc的框架下实现的. 1.JS中只需要用GET模式请求导出就可以了: $('#word-export-btn').parent().on('click',function(){ var promotionWord = JSON.stringify($('#mainForm').serializeObject()); location.href="${ctx}/promotionW

  • JavaWeb动态导出Excel可弹出下载

    由于项目需求,需要将数据导出成Excel表格,并且可选择导出项,可下载.项目使用的Spring+Mybatis+SpringMVC框架,利用Apache POI导出Excel.POI具体使用请自行百度.话不多说,上代码. ExportExcelUtil代码 package com.rixin.common.util; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.URLEncoder;

  • java常用工具类之Excel操作类及依赖包下载

    依赖包下载:http://xiazai.jb51.net/201407/tools/java-excel-dependency(jb51.net).rar Excel工具类ExcelUtil.java源码: package com.itjh.javaUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStr

  • java实现excel导入数据的工具类

    导入Excel数据的工具类,调用也就几行代码,很简单的. 复制代码 代码如下: import jxl.Cell;import jxl.Sheet;import jxl.Workbook;import jxl.read.biff.BiffException;import org.apache.commons.beanutils.BeanUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory; import java.io.IOExc

随机推荐