/*
* 第一步:拼装表头和数据
*/
// 放多个sheet的集合
List<Map<String,Object>> datas = new ArrayList<Map<String,Object>>();
//字典项
String typeCode = Tool.getTypeCodeByCategory(belongsCategory);
List<DataDictVO> dataDicts = dataDictService.getDataDictListByTypeCode(typeCode);
List<Map<String,String>> purchaseMethodData = (List<Map<String,String>>) getDataInfoBusiness.getDataSourceList2(params, "TradeGetInfo", "category", belongsCategory, statisticalTime);
//动态表头
List<List<CellInfo>> headerTwo = new LinkedList<List<CellInfo>>();
List<CellInfo> firstTwo = new LinkedList<CellInfo>();
firstTwo.add(new CellInfo("来源系统",2,1));
if(!CollectionUtils.isEmpty(dataDicts)){
for(DataDictVO dict:dataDicts){
firstTwo.add(new CellInfo(dict.getName(),1,1));
}
}
headerTwo.add(firstTwo);
List<CellInfo> second = new LinkedList<CellInfo>();
int colNum = 1;
second.add(new CellInfo("来源系统"));
if(!CollectionUtils.isEmpty(dataDicts)){
for(int i=0;i<dataDicts.size();i++){
second.add(new CellInfo("入库"));
colNum += 1;
}
}
headerTwo.add(second);
//表数据
List<List<CellInfo>> dataTwo = new LinkedList<List<CellInfo>>(); for(Map<String,String> typeData:purchaseMethodData){
List<CellInfo> row = new LinkedList<CellInfo>();
row.add(new CellInfo(typeData.get("DATA_SOURCE_CODE_NAME")));
for(DataDictVO dict:dataDicts){
String code = dict.getCode() + "_ACCESS_NUM";
row.add(new CellInfo(typeData.get(code)));
}
dataTwo.add(row);
} Map<String, Object> mapTwo = new HashMap<String, Object>();
mapTwo.put("sheetName", "按类别统计");
mapTwo.put("title", "按类别统计");
mapTwo.put("unitInfo", "");
mapTwo.put("headerLength", colNum);
mapTwo.put("header", headerTwo);
mapTwo.put("data", dataTwo);
datas.add(mapTwo);
/*
* 第二步:调用工具类
*/
/**
* 导出成Excel表格
* @param sheetName sheet名称 该类多Sheet
* @param title 表格的title。eg:政府采购
* @param unitInfo 表格单位信息。eg:金额单位:万元
* @param headerLength 表头的最大列数(按未合并前的单元格算)
* @param header 表头信息(见CellInfo)如果跨行则被合并的行不再需要说明跨行信息 即:跨行信息放在第一行出现该信息的CellInfo里。后面的每行只需要输入相同的内容即可。
* @param data 同表头
* @param out 输出流 将生成的Excel数据流传输到该输出流
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static HSSFWorkbook exportExcel(List<Map<String,Object>> datas) throws IOException{
//创建工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
//表头的样式
HSSFCellStyle titlestyle = workbook.createCellStyle();// 创建样式对象
titlestyle.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
titlestyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
// titlestyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
// titlestyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//字体
HSSFFont titleFont = workbook.createFont(); // 创建字体对象
titleFont.setFontHeightInPoints((short) 11); // 设置字体大小
titleFont.setFontName("微软雅黑"); // 设置为黑体字
// titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体
titlestyle.setFont(titleFont);
//指定当单元格内容显示不下时自动换行
titlestyle.setWrapText(true);
//表数据的样式
HSSFCellStyle style = workbook.createCellStyle();// 创建样式对象
style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
//字体
HSSFFont font = workbook.createFont(); // 创建字体对象
font.setFontHeightInPoints((short) 11); // 设置字体大小
font.setFontName("微软雅黑"); // 设置为黑体字
style.setFont(font);
//指定当单元格内容显示不下时自动换行
style.setWrapText(true);
for(Map<String,Object> map:datas){
String sheetName = map.get("sheetName").toString();
String title = map.get("title").toString();
String unitInfo = map.get("unitInfo").toString();
int headerLength = (int)map.get("headerLength");
List<List<CellInfo>> header = (List<List<CellInfo>>)map.get("header");
List<List<CellInfo>> data = (List<List<CellInfo>>)map.get("data");
//创建Sheet
HSSFSheet sheet = workbook.createSheet(sheetName);
//设置表格默认列宽度为20个字节
sheet.setDefaultColumnWidth(20);
//设置第一行 (单位信息,定制)
int rowNum = 0;
if(null!=unitInfo){
sheet.addMergedRegion(new CellRangeAddress(rowNum,1,0,headerLength-1));
HSSFRow rowUnit = sheet.createRow(rowNum);
HSSFCell cellUnit = rowUnit.createCell(0);
HSSFCellStyle unitStyle = workbook.createCellStyle();// 创建样式对象
unitStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
unitStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
unitStyle.setFont(font);
cellUnit.setCellStyle(unitStyle);
cellUnit.setCellValue(unitInfo);
rowNum =1;
}
//标题
if(null!=title){
rowNum++;
HSSFRow rowHeader = sheet.createRow(rowNum);
for(int i=0;i<headerLength;i++){
HSSFCell cellHeader = rowHeader.createCell(i);
cellHeader.setCellStyle(titlestyle);
cellHeader.setCellValue(title);
}
rowNum++;
HSSFRow title2 = sheet.createRow(rowNum);
for(int i=0;i<headerLength;i++){
HSSFCell cellHeader = title2.createCell(i);
cellHeader.setCellStyle(titlestyle);
cellHeader.setCellValue(title);
}
sheet.addMergedRegion(new CellRangeAddress(rowNum-1,rowNum,0,headerLength-1));
} //表头
for (int i = 0; i < header.size(); i++) {
//行
rowNum ++;
HSSFRow row = sheet.createRow(rowNum);
List<CellInfo> cols = header.get(i);
//创建列
int colNum = 0;
for(int j=0;j<cols.size();j++){
HSSFCell cell = row.createCell(colNum);
cell.setCellStyle(titlestyle);
cell.setCellValue(cols.get(j).getContent());
int firstRow = rowNum;
int lastRow =rowNum;
int firstCol = colNum;
int lastCol = colNum;
boolean merge = false;
if(cols.get(j).getRowSpan()>1){
lastRow += cols.get(j).getRowSpan()-1;
merge = true;
}
//如果跨行则先创建被合并的单元格(主要是不创建的话,合并后的样式引用有问题)
if(cols.get(j).getColSpan()>1){
for(int k=0;k<cols.get(j).getColSpan()-1;k++){
colNum++;
HSSFCell tmpCell = row.createCell(colNum);
tmpCell.setCellStyle(titlestyle);
tmpCell.setCellValue(cols.get(j).getContent());
}
lastCol = colNum;
merge = true;
}
colNum++;
if(merge){
sheet.addMergedRegion(new CellRangeAddress(firstRow,lastRow,firstCol,lastCol));
}
}
}
//表格数据
for (int i = 0; i < data.size(); i++) {
//行
rowNum ++;
HSSFRow row = sheet.createRow(rowNum);
List<CellInfo> cols = data.get(i);
//创建列
int colNum = 0;
for(int j=0;j<cols.size();j++){
HSSFCell cell = row.createCell(colNum);
cell.setCellStyle(style);
cell.setCellValue(cols.get(j).getContent());
int firstRow = rowNum;
int lastRow =rowNum;
int firstCol = colNum;
int lastCol = colNum;
boolean merge = false;
if(cols.get(j).getRowSpan()>1){
lastRow += cols.get(j).getRowSpan()-1;
merge = true;
}
//如果跨行则先创建被合并的单元格(主要是不创建的话,合并后的样式引用有问题)
if(cols.get(j).getColSpan()>1){
for(int k=0;k<cols.get(j).getColSpan()-1;k++){
colNum++;
HSSFCell tmpCell = row.createCell(colNum);
tmpCell.setCellStyle(style);
tmpCell.setCellValue(cols.get(j).getContent());
}
lastCol = colNum;
merge = true;
}
colNum++;
if(merge){
sheet.addMergedRegion(new CellRangeAddress(firstRow,lastRow,firstCol,lastCol));
}
}
}
rowNum++; //页底样式
HSSFCellStyle footerStyle = workbook.createCellStyle();// 创建样式对象
footerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
footerStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
footerStyle.setFont(font); int n = headerLength/4;
int m = headerLength%4;
int start = 0;
int end = n;
HSSFRow footer = sheet.createRow(rowNum);
HSSFCell unitFooter = footer.createCell(0);
unitFooter.setCellStyle(footerStyle);
unitFooter.setCellValue("填报单位:"); if(m>0){
end += 1;
}
sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1)); start = end;
HSSFCell timeFooter = footer.createCell(start);
timeFooter.setCellStyle(footerStyle);
timeFooter.setCellValue("填报时间:");
if(m>1){
end += n+1;
}else{
end += n;
}
sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1)); start = end;
HSSFCell personFooter = footer.createCell(start);
personFooter.setCellStyle(footerStyle);
personFooter.setCellValue("填报人:");
if(m>2){
end += n+1;
}else{
end += n;
}
sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1)); start = end;
HSSFCell telFooter = footer.createCell(start);
telFooter.setCellStyle(footerStyle);
telFooter.setCellValue("联系电话:");
sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,headerLength-1));
}
return workbook;
} /**
* 解决 导出excel 文件名 为中文时乱码的问题
* @param fileName 文件名
* @return
*/
public static String toUtf8String(String fileName) {
try {
return new String(fileName.getBytes("GBK"), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return fileName;
}
/**
*
* 表格内容信息
* <p>
* 表格类每个单元格信息
* </p>
* @author qinwb
* @since jdk1.7
* 2017年3月21日
*
*/ public class CellInfo { /**
* 内容:默认为空
*/
private String content = "";
/**
* 跨列:默认跨1列
*/
private int colSpan = 1;
/**
* 跨行:默认跨1行
*/
private int rowSpan = 1; public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getColSpan() {
return colSpan;
}
public void setColSpan(int colSpan) {
this.colSpan = colSpan;
}
public int getRowSpan() {
return rowSpan;
}
public void setRowSpan(int rowSpan) {
this.rowSpan = rowSpan;
}
public CellInfo() {
}
public CellInfo(String content, int rowSpan, int colSpan) {
super();
this.content = content;
this.rowSpan = rowSpan;
this.colSpan = colSpan;
}
public CellInfo(String content) {
super();
this.content = content;
}
}

 

poi导出excel,表头数据动态拼装的更多相关文章

  1. java中使用poi导出excel表格数据并且可以手动修改导出路径

    在我们开发项目中,很多时候会提出这样的需求:将前端的某某数据以excel表格导出,今天就给大家写一个简单的模板. 这里我们选择使用poi导出excel: 第一步:导入需要的jar包到 lib 文件夹下

  2. 使用NPOI或POI 导出Excel大数据(百万级以上),导致内存溢出的解决方案(NPOI,POI)

    使用工具:POI(JAVA),NPOI(.Net) 致谢博主 Crazy_Jeff 提供的思路 一.问题描述: 导出任务数据量近100W甚至更多,导出的项目就会内存溢出,挂掉. 二.原因分析: 1.每 ...

  3. poi导出excel数据量过大

    问题:使用poi导出excel,数据量过大导致内存溢出 解决思路:1.多sheet导出 2.生成多个excel打包下载 3.生成csv下载 本文使用的是第二个思路,代码如下: poiUtil工具类 p ...

  4. 使用POI导出EXCEL工具类并解决导出数据量大的问题

    POI导出工具类 工作中常常会遇到一些图表需要导出的功能,在这里自己写了一个工具类方便以后使用(使用POI实现). 项目依赖 <dependency> <groupId>org ...

  5. 复杂的POI导出Excel表格(多行表头、合并单元格)

    poi导出excel有两种方式: 第一种:从无到有的创建整个excel,通过HSSFWorkbook,HSSFSheet HSSFCell, 等对象一步一步的创建出工作簿,sheet,和单元格,并添加 ...

  6. POI导出EXCEL经典实现

    1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则 ...

  7. Java POI 导出EXCEL经典实现 Java导出Excel

    转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...

  8. 重构:以Java POI 导出EXCEL为例

    重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...

  9. 重构:以Java POI 导出EXCEL为例2

    前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...

随机推荐

  1. 在 浏览器中调用外接设备— —手写板 【win10 x64 手动注册ocx控件的方法】

    PPAXSignToolSDK.ocx 浏览器下使用手写板时调用的控件,使用前必须先注册,,不然浏览器下版本无法正常工作. ocx 控件在安装包运行时会自动注册,如果安装包没有注册成功,需要进行手动注 ...

  2. c# 读取xml 某个节点值

    一.xml格式如下: <?xml version="1.0" encoding="UTF-8"?><Freight> <freig ...

  3. Android线程

    1.引言 在Android中,几乎完全采用了Java的线程机制,由于Android的特性,主线程只处理和界面相关的事情,子线程处理耗时操作.Android中扮演线程角色的有Thread.AsyncTa ...

  4. 浅析requests库响应对象的text和content属性

    在做爬虫时请求网页的requests库是必不可少的,我们常常会用到 res = resquests.get(url) 方法,在获取网页的html代码时常常使用res的text属性: html = re ...

  5. REM在edge浏览器中不重新计算解决

    经过多分析和排查,此问题解决的方案 第一种: 在CSS样式中添加 body { font-size:100% } 如果不起作用,可以尝试将引用的REMjs放在head内引用

  6. loadrunner 场景设计-添加Windows Resources计数器

    场景设计-添加Windows Resources计数器 by:授客 QQ:1033553122 目的 监控要测试的windows服务器的资源使用情况 步骤 1.添加视图,方法双击.拖动左侧的Windo ...

  7. Java String和Date的转换

    String—>Date方法一: String dateString = "2016-01-08"; try { SimpleDateFormat sdf = new Sim ...

  8. (网页)Uncaught ReferenceError: pageImport is not defined

    在js开发中,很多人遇到类似问题,都找不到解决方法.Uncaught ReferenceError: $ is not defined,在这里给大家提供几个解决方法. 1.出现这个错误,最可能的是引用 ...

  9. CentOS7的/tmp目录自动清理规则

    CentOS6以下系统(含)使用watchtmp + cron来实现定时清理临时文件的效果,这点在CentOS7发生了变化. 在CentOS7下,系统使用systemd管理易变与临时文件,与之相关的系 ...

  10. weblogic系列漏洞整理 -- 3. weblogic 后台提权

    目录 三. weblogic 后台提权 0. 思路分析 1. 利用过程 2. 提示和技巧 一.weblogic安装 http://www.cnblogs.com/0x4D75/p/8916428.ht ...