1. /*
  2. * 第一步:拼装表头和数据
  3. */
  4. // 放多个sheet的集合
  5. List<Map<String,Object>> datas = new ArrayList<Map<String,Object>>();
  6. //字典项
  7. String typeCode = Tool.getTypeCodeByCategory(belongsCategory);
  8. List<DataDictVO> dataDicts = dataDictService.getDataDictListByTypeCode(typeCode);
  9. List<Map<String,String>> purchaseMethodData = (List<Map<String,String>>) getDataInfoBusiness.getDataSourceList2(params, "TradeGetInfo", "category", belongsCategory, statisticalTime);
  10. //动态表头
  11. List<List<CellInfo>> headerTwo = new LinkedList<List<CellInfo>>();
  12. List<CellInfo> firstTwo = new LinkedList<CellInfo>();
  13. firstTwo.add(new CellInfo("来源系统",2,1));
  14. if(!CollectionUtils.isEmpty(dataDicts)){
  15. for(DataDictVO dict:dataDicts){
  16. firstTwo.add(new CellInfo(dict.getName(),1,1));
  17. }
  18. }
  19. headerTwo.add(firstTwo);
  20. List<CellInfo> second = new LinkedList<CellInfo>();
  21. int colNum = 1;
  22. second.add(new CellInfo("来源系统"));
  23. if(!CollectionUtils.isEmpty(dataDicts)){
  24. for(int i=0;i<dataDicts.size();i++){
  25. second.add(new CellInfo("入库"));
  26. colNum += 1;
  27. }
  28. }
  29. headerTwo.add(second);
  30. //表数据
  31. List<List<CellInfo>> dataTwo = new LinkedList<List<CellInfo>>();
  32.  
  33. for(Map<String,String> typeData:purchaseMethodData){
  34. List<CellInfo> row = new LinkedList<CellInfo>();
  35. row.add(new CellInfo(typeData.get("DATA_SOURCE_CODE_NAME")));
  36. for(DataDictVO dict:dataDicts){
  37. String code = dict.getCode() + "_ACCESS_NUM";
  38. row.add(new CellInfo(typeData.get(code)));
  39. }
  40. dataTwo.add(row);
  41. }
  42.  
  43. Map<String, Object> mapTwo = new HashMap<String, Object>();
  44. mapTwo.put("sheetName", "按类别统计");
  45. mapTwo.put("title", "按类别统计");
  46. mapTwo.put("unitInfo", "");
  47. mapTwo.put("headerLength", colNum);
  48. mapTwo.put("header", headerTwo);
  49. mapTwo.put("data", dataTwo);
  50. datas.add(mapTwo);
  51. /*
  52. * 第二步:调用工具类
  53. */
  54. /**
  55. * 导出成Excel表格
  56. * @param sheetName sheet名称 该类多Sheet
  57. * @param title 表格的title。eg:政府采购
  58. * @param unitInfo 表格单位信息。eg:金额单位:万元
  59. * @param headerLength 表头的最大列数(按未合并前的单元格算)
  60. * @param header 表头信息(见CellInfo)如果跨行则被合并的行不再需要说明跨行信息 即:跨行信息放在第一行出现该信息的CellInfo里。后面的每行只需要输入相同的内容即可。
  61. * @param data 同表头
  62. * @param out 输出流 将生成的Excel数据流传输到该输出流
  63. * @throws IOException
  64. */
  65. @SuppressWarnings("unchecked")
  66. public static HSSFWorkbook exportExcel(List<Map<String,Object>> datas) throws IOException{
  67. //创建工作簿
  68. HSSFWorkbook workbook = new HSSFWorkbook();
  69. //表头的样式
  70. HSSFCellStyle titlestyle = workbook.createCellStyle();// 创建样式对象
  71. titlestyle.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
  72. titlestyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
  73. titlestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  74. titlestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  75. titlestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
  76. titlestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
  77. // titlestyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
  78. // titlestyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  79. //字体
  80. HSSFFont titleFont = workbook.createFont(); // 创建字体对象
  81. titleFont.setFontHeightInPoints((short) 11); // 设置字体大小
  82. titleFont.setFontName("微软雅黑"); // 设置为黑体字
  83. // titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体
  84. titlestyle.setFont(titleFont);
  85. //指定当单元格内容显示不下时自动换行
  86. titlestyle.setWrapText(true);
  87. //表数据的样式
  88. HSSFCellStyle style = workbook.createCellStyle();// 创建样式对象
  89. style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
  90. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
  91. style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  92. style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  93. style.setBorderRight(HSSFCellStyle.BORDER_THIN);
  94. style.setBorderTop(HSSFCellStyle.BORDER_THIN);
  95. //字体
  96. HSSFFont font = workbook.createFont(); // 创建字体对象
  97. font.setFontHeightInPoints((short) 11); // 设置字体大小
  98. font.setFontName("微软雅黑"); // 设置为黑体字
  99. style.setFont(font);
  100. //指定当单元格内容显示不下时自动换行
  101. style.setWrapText(true);
  102. for(Map<String,Object> map:datas){
  103. String sheetName = map.get("sheetName").toString();
  104. String title = map.get("title").toString();
  105. String unitInfo = map.get("unitInfo").toString();
  106. int headerLength = (int)map.get("headerLength");
  107. List<List<CellInfo>> header = (List<List<CellInfo>>)map.get("header");
  108. List<List<CellInfo>> data = (List<List<CellInfo>>)map.get("data");
  109. //创建Sheet
  110. HSSFSheet sheet = workbook.createSheet(sheetName);
  111. //设置表格默认列宽度为20个字节
  112. sheet.setDefaultColumnWidth(20);
  113. //设置第一行 (单位信息,定制)
  114. int rowNum = 0;
  115. if(null!=unitInfo){
  116. sheet.addMergedRegion(new CellRangeAddress(rowNum,1,0,headerLength-1));
  117. HSSFRow rowUnit = sheet.createRow(rowNum);
  118. HSSFCell cellUnit = rowUnit.createCell(0);
  119. HSSFCellStyle unitStyle = workbook.createCellStyle();// 创建样式对象
  120. unitStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
  121. unitStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
  122. unitStyle.setFont(font);
  123. cellUnit.setCellStyle(unitStyle);
  124. cellUnit.setCellValue(unitInfo);
  125. rowNum =1;
  126. }
  127. //标题
  128. if(null!=title){
  129. rowNum++;
  130. HSSFRow rowHeader = sheet.createRow(rowNum);
  131. for(int i=0;i<headerLength;i++){
  132. HSSFCell cellHeader = rowHeader.createCell(i);
  133. cellHeader.setCellStyle(titlestyle);
  134. cellHeader.setCellValue(title);
  135. }
  136. rowNum++;
  137. HSSFRow title2 = sheet.createRow(rowNum);
  138. for(int i=0;i<headerLength;i++){
  139. HSSFCell cellHeader = title2.createCell(i);
  140. cellHeader.setCellStyle(titlestyle);
  141. cellHeader.setCellValue(title);
  142. }
  143. sheet.addMergedRegion(new CellRangeAddress(rowNum-1,rowNum,0,headerLength-1));
  144. }
  145.  
  146. //表头
  147. for (int i = 0; i < header.size(); i++) {
  148. //行
  149. rowNum ++;
  150. HSSFRow row = sheet.createRow(rowNum);
  151. List<CellInfo> cols = header.get(i);
  152. //创建列
  153. int colNum = 0;
  154. for(int j=0;j<cols.size();j++){
  155. HSSFCell cell = row.createCell(colNum);
  156. cell.setCellStyle(titlestyle);
  157. cell.setCellValue(cols.get(j).getContent());
  158. int firstRow = rowNum;
  159. int lastRow =rowNum;
  160. int firstCol = colNum;
  161. int lastCol = colNum;
  162. boolean merge = false;
  163. if(cols.get(j).getRowSpan()>1){
  164. lastRow += cols.get(j).getRowSpan()-1;
  165. merge = true;
  166. }
  167. //如果跨行则先创建被合并的单元格(主要是不创建的话,合并后的样式引用有问题)
  168. if(cols.get(j).getColSpan()>1){
  169. for(int k=0;k<cols.get(j).getColSpan()-1;k++){
  170. colNum++;
  171. HSSFCell tmpCell = row.createCell(colNum);
  172. tmpCell.setCellStyle(titlestyle);
  173. tmpCell.setCellValue(cols.get(j).getContent());
  174. }
  175. lastCol = colNum;
  176. merge = true;
  177. }
  178. colNum++;
  179. if(merge){
  180. sheet.addMergedRegion(new CellRangeAddress(firstRow,lastRow,firstCol,lastCol));
  181. }
  182. }
  183. }
  184. //表格数据
  185. for (int i = 0; i < data.size(); i++) {
  186. //行
  187. rowNum ++;
  188. HSSFRow row = sheet.createRow(rowNum);
  189. List<CellInfo> cols = data.get(i);
  190. //创建列
  191. int colNum = 0;
  192. for(int j=0;j<cols.size();j++){
  193. HSSFCell cell = row.createCell(colNum);
  194. cell.setCellStyle(style);
  195. cell.setCellValue(cols.get(j).getContent());
  196. int firstRow = rowNum;
  197. int lastRow =rowNum;
  198. int firstCol = colNum;
  199. int lastCol = colNum;
  200. boolean merge = false;
  201. if(cols.get(j).getRowSpan()>1){
  202. lastRow += cols.get(j).getRowSpan()-1;
  203. merge = true;
  204. }
  205. //如果跨行则先创建被合并的单元格(主要是不创建的话,合并后的样式引用有问题)
  206. if(cols.get(j).getColSpan()>1){
  207. for(int k=0;k<cols.get(j).getColSpan()-1;k++){
  208. colNum++;
  209. HSSFCell tmpCell = row.createCell(colNum);
  210. tmpCell.setCellStyle(style);
  211. tmpCell.setCellValue(cols.get(j).getContent());
  212. }
  213. lastCol = colNum;
  214. merge = true;
  215. }
  216. colNum++;
  217. if(merge){
  218. sheet.addMergedRegion(new CellRangeAddress(firstRow,lastRow,firstCol,lastCol));
  219. }
  220. }
  221. }
  222. rowNum++;
  223.  
  224. //页底样式
  225. HSSFCellStyle footerStyle = workbook.createCellStyle();// 创建样式对象
  226. footerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
  227. footerStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
  228. footerStyle.setFont(font);
  229.  
  230. int n = headerLength/4;
  231. int m = headerLength%4;
  232. int start = 0;
  233. int end = n;
  234. HSSFRow footer = sheet.createRow(rowNum);
  235. HSSFCell unitFooter = footer.createCell(0);
  236. unitFooter.setCellStyle(footerStyle);
  237. unitFooter.setCellValue("填报单位:");
  238.  
  239. if(m>0){
  240. end += 1;
  241. }
  242. sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1));
  243.  
  244. start = end;
  245. HSSFCell timeFooter = footer.createCell(start);
  246. timeFooter.setCellStyle(footerStyle);
  247. timeFooter.setCellValue("填报时间:");
  248. if(m>1){
  249. end += n+1;
  250. }else{
  251. end += n;
  252. }
  253. sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1));
  254.  
  255. start = end;
  256. HSSFCell personFooter = footer.createCell(start);
  257. personFooter.setCellStyle(footerStyle);
  258. personFooter.setCellValue("填报人:");
  259. if(m>2){
  260. end += n+1;
  261. }else{
  262. end += n;
  263. }
  264. sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,end-1));
  265.  
  266. start = end;
  267. HSSFCell telFooter = footer.createCell(start);
  268. telFooter.setCellStyle(footerStyle);
  269. telFooter.setCellValue("联系电话:");
  270. sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum+1,start,headerLength-1));
  271. }
  272. return workbook;
  273. }
  274.  
  275. /**
  276. * 解决 导出excel 文件名 为中文时乱码的问题
  277. * @param fileName 文件名
  278. * @return
  279. */
  280. public static String toUtf8String(String fileName) {
  281. try {
  282. return new String(fileName.getBytes("GBK"), "ISO8859-1");
  283. } catch (UnsupportedEncodingException e) {
  284. e.printStackTrace();
  285. }
  286. return fileName;
  287. }
  1. /**
  2. *
  3. * 表格内容信息
  4. * <p>
  5. * 表格类每个单元格信息
  6. * </p>
  7. * @author qinwb
  8. * @since jdk1.7
  9. * 2017年3月21日
  10. *
  11. */
  12.  
  13. public class CellInfo {
  14.  
  15. /**
  16. * 内容:默认为空
  17. */
  18. private String content = "";
  19. /**
  20. * 跨列:默认跨1列
  21. */
  22. private int colSpan = 1;
  23. /**
  24. * 跨行:默认跨1行
  25. */
  26. private int rowSpan = 1;
  27.  
  28. public String getContent() {
  29. return content;
  30. }
  31. public void setContent(String content) {
  32. this.content = content;
  33. }
  34. public int getColSpan() {
  35. return colSpan;
  36. }
  37. public void setColSpan(int colSpan) {
  38. this.colSpan = colSpan;
  39. }
  40. public int getRowSpan() {
  41. return rowSpan;
  42. }
  43. public void setRowSpan(int rowSpan) {
  44. this.rowSpan = rowSpan;
  45. }
  46. public CellInfo() {
  47. }
  48. public CellInfo(String content, int rowSpan, int colSpan) {
  49. super();
  50. this.content = content;
  51. this.rowSpan = rowSpan;
  52. this.colSpan = colSpan;
  53. }
  54. public CellInfo(String content) {
  55. super();
  56. this.content = content;
  57. }
  58. }
  1.  
  1.  

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. 近期ASP.NET问题汇总及对应的解决办法

    1. 使用SQL统计一个字符串中指定字符的个数,示例(统计0的个数): ','')) 2. 使用Forms认证,客户端本地时间不对无法登陆系统,解决办法: FormsAuthentication.Re ...

  2. (3)Microsoft office Word 2013版本操作入门_段落设定

    1.查看文件: 打开word查看左下角 会显示 word一共有多少页,当前第几页,共多少字等,如下图所示 2.word快速翻页: Ctrl+PageDown  向下翻页, Ctrl+PageUp 向上 ...

  3. 【Java并发编程】18、PriorityBlockingQueue源码分析

    PriorityBlockingQueue是一个基于数组实现的线程安全的无界队列,原理和内部结构跟PriorityQueue基本一样,只是多了个线程安全.javadoc里面提到一句,1:理论上是无界的 ...

  4. 【Java深入研究】7、ThreadLocal详解

    ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线 ...

  5. prototype、proto和constructor的三角关系

    转载整理自http://www.cnblogs.com/xiaohuochai/p/5721552.html#3760057 http://blog.csdn.net/jasonzds/article ...

  6. JavaScript初学者必看“new”

    译者按: 本文简单的介绍了new, 更多的是介绍原型(prototype),值得一读. 原文: JavaScript For Beginners: the 'new' operator 译者: Fun ...

  7. jsPlumb.jsAPI阅读笔记(官方文档翻译)

    jsPlumb DOCS 公司要开始做流程控制器,所以先调研下jsPlumb,下文是阅读jsPlumb提供的document所产生的归纳总结 setup 如果不使用jQuery或者类jQuery库,则 ...

  8. 【BI学习笔记】适合集成到项目里的BI:Wyn Enterprise

    近日,我收到葡萄城的邮件,讲葡萄城开始进军BI领域,发布了一套BI和报表工具,叫Wyn Enterprise. 之前了解过PowerBI等面向终端用户的BI工具,我发现BI工具与Wyn Enterpr ...

  9. Android RecycleView 自定义Item的使用

    自定义布局的RecycleView需要自己实现Adapter,ViewHolder和布局: 自定义Adapter继承RecycleView.Adapter,重写getItemCount(),onBin ...

  10. Scrapy爬虫入门

    1.安装Scrapy 打开Anaconda Prompt,执行:pip install Scrapy执行安装! 注意:要是安装过程中抛出: error: Microsoft Visual C++ 14 ...