使用POI导出Excel(二)-利用模板
一、基本操作见: 使用POI导出Excel
二、本次功能需求
给了一个模板,里面有6个sheet页,每页里面都需要填充相应的数据。如图:


三、需求分析
1、分了6个sheet页,每页的数据都不一样,首先代码里要获得它们的数据,然后6个sheet页只能一个个填进去,没法批量操作。
2、如果直接代码创建Excel并画表格样式和数据,那么工程量将会很大,而且会导致代码很乱。我采用的方法是把模板保存到项目里,再通过路径获取到该模板文件,把其内容全部复制到新创建的Excel中,再往里填充数据。
3、注意到第一张图中有总计这一行,我的建议是先在代码中计算出相应的数据,再填充,我也是这样做的。当然,我的第一想法是给它设置函数公式,但是后来我并没有这么做。
4、从第二张图中可以看得出要填充的数据的行是不固定的,除非规定了只填充前几条数据。而在11、12行中的数据是已经有了的,当填充的数据太多,就会覆盖掉那行数据。有两种方法解决,一是把它获取到,先填充数据覆盖掉,再在最后一条数据的下一行把它再填充回去。二是根据数据的总条数通过代码往中间插入空白行。两种方法都可行,我采用了第二种。
四、上代码
public void exportAll() {
OutputStream out = null;
try {
// 获取数据
List<BaseTalentFlowAnalysisGridVo> talentFlows = this.talentFlowQuestionnaireService.listAnalysis();
List<BaseBasicSituationAnalysisGridVo> basicSituations = this.basicSituationService.listAnalysis();
List<BaseTalentInputAnalysisGridVo> talentInputs = this.talentInputService.listAnalysis();
List<BaseTalentDemandAnalysisGridVo> talentDemands = this.talentDemandService.listAnalysis();
List<BaseHighLevelTalentsRosterAnalysisGridVo> talentRosters = this.rosterService.listAnalysis();
Map<String, Object> results = new HashMap<>();
results.put("talentFlows", talentFlows);
results.put("basicSituations", basicSituations);
results.put("talentInputs", talentInputs);
results.put("talentDemands", talentDemands);
results.put("talentRosters", talentRosters);
// 拿到模板文件
String path = ServletActionContext.getServletContext().getRealPath("/");
String filePath = path + "\\resources\\temp\\人才统计报表模板.xls";
FileInputStream tps = new FileInputStream(new File(filePath));
final HSSFWorkbook tpWorkbook = new HSSFWorkbook(tps);
out = response.getOutputStream();
response.reset();
response.setHeader("content-disposition",
"attachment;filename=" + new String(("人才统计报表").getBytes("gb2312"), "ISO8859-1") + ".xls");
response.setContentType("APPLICATION/msexcel");
// 新建一个Excel的工作空间
HSSFWorkbook workbook = new HSSFWorkbook();
// 把模板复制到新建的Excel
workbook = tpWorkbook;
// 填充数据
this.excelService.addData(workbook, results);
// 输出Excel内容,生成Excel文件
workbook.write(out);
} catch (final IOException e) {
LOGGER.error(e);
} catch (final IllegalArgumentException e) {
LOGGER.error(e);
} catch (final Exception e) {
LOGGER.error(e);
} finally {
try {
// 最后记得关闭输出流
response.flushBuffer();
if (out != null) {
out.flush();
out.close();
}
} catch (final IOException e) {
LOGGER.error(e);
}
}
}
/**
* 第二个sheet页:人才流动情况表
*
* @param workbook
* @param talentFlows
*/
private void addTalentFlows(HSSFWorkbook workbook, List<BaseTalentFlowAnalysisGridVo> talentFlows) {
// 获取第二个sheet页
Sheet talentFlowSheet = workbook.getSheetAt(1);
Row talentFlowRow = talentFlowSheet.getRow(0);
// 声明总计的那几个数据
Integer totalLastYearTotal = 0;
Integer totalHighLevelTalent = 0;
Integer totalUndergraduateAndGraduate = 0;
Integer totalCollegeStudents = 0;
Integer totalSocialTalent = 0;
Integer totalMilitaryTransferCadres = 0;
Integer totalReturnees = 0;
Integer totalRetirement = 0;
Integer totalResignation = 0;
Integer totalDismiss = 0;
Integer totalOther = 0;
Integer totalAverageIncrease = 0;
Integer totalAverageReduction = 0;
// 循环数据
for (BaseTalentFlowAnalysisGridVo baseTalentFlowAnalysisGridVo : talentFlows) {
// 循环行
for (int tr = 4; tr < 11; tr++) {
talentFlowRow = talentFlowSheet.getRow(tr);
// 当数据的项目字段和行的第一列内容相等,则把该条数据填入该行
if (talentFlowRow.getCell(0).getStringCellValue()
.equals(baseTalentFlowAnalysisGridVo.getFkProjectName())) {
talentFlowRow.getCell(1).setCellValue(baseTalentFlowAnalysisGridVo.getLastYearTotal());
// 给总计做计算
totalLastYearTotal += baseTalentFlowAnalysisGridVo.getLastYearTotal();
talentFlowRow.getCell(2).setCellValue(baseTalentFlowAnalysisGridVo.getHighLevelTalent());
totalHighLevelTalent += baseTalentFlowAnalysisGridVo.getHighLevelTalent();
talentFlowRow.getCell(3).setCellValue(baseTalentFlowAnalysisGridVo.getUndergraduateAndGraduate());
totalUndergraduateAndGraduate += baseTalentFlowAnalysisGridVo.getUndergraduateAndGraduate();
talentFlowRow.getCell(4).setCellValue(baseTalentFlowAnalysisGridVo.getCollegeStudents());
totalCollegeStudents += baseTalentFlowAnalysisGridVo.getCollegeStudents();
talentFlowRow.getCell(5).setCellValue(baseTalentFlowAnalysisGridVo.getSocialTalent());
totalSocialTalent += baseTalentFlowAnalysisGridVo.getSocialTalent();
talentFlowRow.getCell(6).setCellValue(baseTalentFlowAnalysisGridVo.getMilitaryTransferCadres());
totalMilitaryTransferCadres += baseTalentFlowAnalysisGridVo.getMilitaryTransferCadres();
talentFlowRow.getCell(7).setCellValue(baseTalentFlowAnalysisGridVo.getReturnees());
totalReturnees += baseTalentFlowAnalysisGridVo.getReturnees();
talentFlowRow.getCell(8).setCellValue(baseTalentFlowAnalysisGridVo.getRetirement());
totalRetirement += baseTalentFlowAnalysisGridVo.getRetirement();
talentFlowRow.getCell(9).setCellValue(baseTalentFlowAnalysisGridVo.getResignation());
totalResignation += baseTalentFlowAnalysisGridVo.getResignation();
talentFlowRow.getCell(10).setCellValue(baseTalentFlowAnalysisGridVo.getDismiss());
totalDismiss += baseTalentFlowAnalysisGridVo.getDismiss();
talentFlowRow.getCell(11).setCellValue(baseTalentFlowAnalysisGridVo.getOther());
totalOther += baseTalentFlowAnalysisGridVo.getOther();
talentFlowRow.getCell(12).setCellValue(baseTalentFlowAnalysisGridVo.getAverageIncrease());
totalAverageIncrease += baseTalentFlowAnalysisGridVo.getAverageIncrease();
talentFlowRow.getCell(13).setCellValue(baseTalentFlowAnalysisGridVo.getAverageReduction());
totalAverageReduction += baseTalentFlowAnalysisGridVo.getAverageReduction();
break;
}
}
}
// 给总计行填充数据
talentFlowRow = talentFlowSheet.getRow(11);
talentFlowRow.getCell(1).setCellValue(totalLastYearTotal);
talentFlowRow.getCell(2).setCellValue(totalHighLevelTalent);
talentFlowRow.getCell(3).setCellValue(totalUndergraduateAndGraduate);
talentFlowRow.getCell(4).setCellValue(totalCollegeStudents);
talentFlowRow.getCell(5).setCellValue(totalSocialTalent);
talentFlowRow.getCell(6).setCellValue(totalMilitaryTransferCadres);
talentFlowRow.getCell(7).setCellValue(totalReturnees);
talentFlowRow.getCell(8).setCellValue(totalRetirement);
talentFlowRow.getCell(9).setCellValue(totalResignation);
talentFlowRow.getCell(10).setCellValue(totalDismiss);
talentFlowRow.getCell(11).setCellValue(totalOther);
talentFlowRow.getCell(12).setCellValue(totalAverageIncrease);
talentFlowRow.getCell(13).setCellValue(totalAverageReduction);
}
/**
* 第四个sheet页:人才需求情况调查表
*
* @param workbook
* @param talentFlows
*/
private void addalentDemands(HSSFWorkbook workbook, List<BaseTalentDemandAnalysisGridVo> talentDemands)
throws IllegalArgumentException, IllegalAccessException {
Sheet talentDemandSheet = workbook.getSheetAt(3);
Row talentDemandRow = talentDemandSheet.getRow(4);
// 如果数据大于模板中的行数,插入行并复制第一行数据的格式
if (talentDemands.size() > 5) {
// 插入行,5是模板中已有的行数
talentDemandSheet.shiftRows(5, talentDemandSheet.getLastRowNum(), talentDemands.size() - 5, true, false);
Row sourceRow = talentDemandSheet.getRow(4);
for (int i = 0; i < talentDemands.size() - 5; i++) {
Row newRow = talentDemandSheet.createRow(4 + i + 1);
newRow.setHeight(sourceRow.getHeight());
for (int j = 0; j < sourceRow.getLastCellNum(); j++) {
Cell templateCell = sourceRow.getCell(j);
if (templateCell != null) {
Cell newCell = newRow.createCell(j);
copyCell(templateCell, newCell);
}
}
}
}
// 填充数据
for (int i = 0; i < talentDemands.size(); i++) {
talentDemandRow = talentDemandSheet.getRow(4 + i);
talentDemandRow.getCell(0).setCellValue(talentDemands.get(i).getPositionTitle());
talentDemandRow.getCell(2).setCellValue(talentDemands.get(i).getDemand());
talentDemandRow.getCell(3).setCellValue(talentDemands.get(i).getAge());
talentDemandRow.getCell(4).setCellValue(talentDemands.get(i).getFkAcademicDegreeName());
talentDemandRow.getCell(5).setCellValue(talentDemands.get(i).getTechnicalTitles());
talentDemandRow.getCell(6).setCellValue(talentDemands.get(i).getProfession());
talentDemandRow.getCell(7).setCellValue(talentDemands.get(i).getFkTalentCategoryName());
talentDemandRow.getCell(8).setCellValue(talentDemands.get(i).getFkServiceFormName());
talentDemandRow.getCell(9).setCellValue(talentDemands.get(i).getProvide());
talentDemandRow.getCell(10).setCellValue(talentDemands.get(i).getOtherCases());
talentDemandRow.getCell(11).setCellValue(talentDemands.get(i).getFkIntentionToChooseName());
}
}
五、缺点:一手烂代码,应该给对象设置对应的中文注释,和模板中的列头一样,然后再通过循环填充数据。这样一个个填上去太傻了。
六、通过实验测试,在getCell的时候,如果那是个合并的单元格,那么该单元格的数据存在了左上角,其他的格内容为空。
使用POI导出Excel(二)-利用模板的更多相关文章
- Java之POI导出Excel(二):多个sheet
相信在大部分的web项目中都会有导出导入Excel的需求,之前我也写过一篇导出单个sheet工作表的文章,没看过的小伙伴可以去看哈,链接也给大家放出来了:导出单个sheet 但是在我们日常的工作中,需 ...
- java中使用poi导出excel表格数据并且可以手动修改导出路径
在我们开发项目中,很多时候会提出这样的需求:将前端的某某数据以excel表格导出,今天就给大家写一个简单的模板. 这里我们选择使用poi导出excel: 第一步:导入需要的jar包到 lib 文件夹下
- Java之POI导出Excel(一):单sheet
相信在大部分的web项目中都会有导出导入Excel的需求,今天我们就来看看如何用Java代码去实现 用POI导出Excel表格. 一.pom引用 pom文件中,添加以下依赖 查看代码 <!-- ...
- POI导出EXCEL经典实现
1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则 ...
- Java POI 导出EXCEL经典实现 Java导出Excel
转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...
- 重构:以Java POI 导出EXCEL为例
重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...
- 重构:以Java POI 导出EXCEL为例2
前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...
- 关于poi导出excel三种方式HSSFWorkbook,SXSSFWorkbook,csv的总结
poi导出excel最常用的是第一种方式HSSFWorkbook,不过这种方式数据量大的话会产生内存溢出问题,SXSSFWorkbook是一种大数据量导出格式,csv是另一种excel导出的一种轻快的 ...
- 关于poi导出excel方式HSSFWorkbook(xls).XSSFWorkbook(xlsx).SXSSFWorkbook.csv的总结
1.HSSFWorkbook(xls) import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermo ...
随机推荐
- (转)rabbitmq.config详细配置参数
rabbitmq.config详细配置参数 Key Documentation tcp_listeners 用于监听 AMQP连接的端口列表(无SSL). 可以包含整数 (即"监听所有接口& ...
- PHP接收json格式的POST数据
/** * 获取 post 参数; 在 content_type 为 application/json 时,自动解析 json * @return array */ private function ...
- zookeeper集群-solrcloud集群
本文只写具体的搭建过程,具体原理请看官网文档.国内博客都是基本上都是通过tomcat搭建的solr,本文是通过内部集成的jetty容器搭建. 一.zookeeper集群搭建 1.安装JAVA环境,版本 ...
- QML事件处理 八
1.MouseArea MouseArea 是一个不可见的项目,通常用来和一个可见的项目配合使用来为其提供鼠标处理.鼠标处理的逻辑可以包含在一个MouseArea项目中. MouseArea的enab ...
- python中小数点后取2位(四舍五入)以及取2位(四舍五不入)
一.小数点后取2位(四舍五入)的方法方法一:round()函数其实这个方法不推荐大家使用,查询资料发现里面的坑其实很多,python2和python3里面的坑还不太一样,在此简单描述一下python3 ...
- 几种Memcache的状态监控的工具,以及安装和使用【linux系统】
1.Memcache-top的简介及安装和用法 简介:memcache-top是用perl语言编写的,可以运行在term下.它能够像top一样显示各个memcached节点的状态变化,其中包括系统管理 ...
- python中 @property
考察 Student 类: class Student(object): def __init__(self, name, score): self.name = name self.score = ...
- STM32端口输入输出模式配置
STM32的IO口模式配置 根据数据手册提供的信息,stm32的io口一共有八种模式,他们分别是: 四种输入模式 上拉输入:通过内部的上拉电阻将一个不确定的信号通过一个电阻拉到高电平. 下拉输入:把电 ...
- 20145325张梓靖 《Java程序设计》第5周学习总结
20145325张梓靖 <Java程序设计>第5周学习总结 教材学习内容总结 try catch Java中所有错误都会被打包为对象.如果某个方法声明会抛出Throwable或子类实例,只 ...
- 【安装】Nginx安装
系统平台:CentOS release 6.5 (Final) 64位. 安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool ...