java实现导出Excel(跨行,跨列)
先来个最终结果样式:
第一步: 传参,后期可根据自己需要进行调整。我这里需要的是
- quarter 代表季度
- dptid 部门编号
根据接受过来的参数进行文档命名。
- UserInfo userInfo=(UserInfo)request.getSession().getAttribute("userInfo");
- String userid=userInfo.getUserID();
- String quarter = request.getParameter("quarter");
- String dptid = request.getParameter("dptid");
- /***********************EXCEL导出部分**************************/
- String str3 = FileInfoTools.getSystemFilePath()
- + "/documentTemp/";
- File file = new File(str3);
- if (!file.exists() && !file.isDirectory()) {
- file.mkdir();
- }
- String names = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date());
- String ourl = str3 + names + "_"+userid+".xls";
- FileOutputStream fos = null;
- String fileName = "";
- try {
- HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄
- fileName = "安全可控导出"+"_"+userid+"_"+names+".xls";
- DBManager dbm = new DBManager();
- System.out.println("quarter+"+quarter+"dptid="+dptid);
- try{
- dbm.newConnection();
- String str = "select departmentname from dpt_department where departmentid='"+dptid+"'"; //获取唯一id
- String dptName = dbm.executeQueryString(str);
- fileName=dptName+"部门安全可控清单汇总"+"_"+userid+"_"+names+".xls";
- //创建sheet页,并写入内容
- createSheet(dbm,wb,getCardInfo(dbm,quarter,dptid));
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- dbm.closeConnection();
- }
- File ff = new File(ourl);
- if (ff.exists()) {
- ff.delete();
- }
- fos = new FileOutputStream(ourl);
- wb.write(fos);
- fos.close();
- String u = "/project/system/fileAction.do?filePath=" + URLEncoder.encode(ourl)
- + "&fileName=" + URLEncoder.encode(fileName);
- response.sendRedirect(u);
- } catch (Exception e) {
- e.printStackTrace();
- }
第二步:创建sheet页签
- public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
- for(int i=;i<vt.size();i++){
- Hashtable ht = (Hashtable)vt.get(i);
- String id = (String)ht.get("id");
- String quarter = (String)ht.get("quarter");
- HSSFSheet sheet = w.createSheet("安全可控清单");
- //写入数据
- wirteSheet(dbm,sheet,w,id,quarter);
- }
- }
我这里页签是固定的名称
可根据自己的需要根据参数来进行判断页签。如果多个页签的话 可以这样:
- public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
- Hashtable temp = (Hashtable)vt.get();
- String id = (String)temp.get("id");
- String quarter = (String)temp.get("quarter");
- System.out.println("DumpExcel.jsp id"+id+"quarter:"+quarter);
- //查询得到当前模板对应的页签
- String sheets = "select a7 from a_templet_col_num where templet_id='"+id+"' group by a7 order by a7 ";
- Vector sheetsVc = dbm.executeQueryVector3LowerCase(sheets.toString());
- if (sheetsVc != null && sheetsVc.size() > ) {
- for (int i = ; i < sheetsVc.size(); i++) {
- Hashtable ht = (Hashtable) sheetsVc.get(i);
- System.out.println("导出的页签:ht"+ht.get("a7"));
- HSSFSheet sheet = w.createSheet(ht.get("a7").toString());
- //写入数据
- wirteSheet(dbm,sheet,w,id,quarter,ht.get("a7").toString());
- }
- }
- }
此处的a7 就是页签的名称 在数据库里有对应。此处id是根据另一个方法里查询的!
多个页签样式
请注意第一处代码处:createSheet()方法
createSheet()方法中调用getCardInfo()方法 此方法就是返回你部门的数据。
- public Vector getCardInfo(DBManager dbm,String quarter,String departmentid) throws Exception{
- String sql = "select id,quarter from a_templet where quarter= "+quarter+" and department="+departmentid;
- Vector vc = dbm.executeQueryVector3LowerCase(sql);
- return vc;
- }
此处可根据需要来进行返回,不做多解释!
第三步:写入数据
每一个页签都会有不同的数据,在创建页签时就会对该页签写入数据。循环操作!
31.创建表头
我此处的数据不存在数据库我是固定的。list命名方式自己定义。我这里定义的意义代表他是报表的第几行数据 col是跨几列属性 可根据自己习惯来进行定义
- //第一列数据
List<Map<String, Object>> listOne = new ArrayList<Map<String, Object>>();
Hashtable htss = new Hashtable();- htss.put("group_name", +year+"年第"+ji+"季度信息技术情况调研表");
- htss.put("col", "");
- listOne.add(htss);
第二列这里的参数col_name 是为了跟数据库的属性进行对比取值。
- //第二列数据
- Hashtable tweDump = new Hashtable();
- tweDump.put("show_name", "代码");
- tweDump.put("col_name", "a1");;
- listTwe.add(tweDump);
- Hashtable tweDump0 = new Hashtable();
- tweDump0.put("show_name", "代码");
- tweDump0.put("col_name", "a2");;
- listTwe.add(tweDump0);
- Hashtable tweDump1 = new Hashtable();
- tweDump1.put("show_name", "名称");
- tweDump1.put("col_name", "a3");;
- listTwe.add(tweDump1);
- Hashtable tweDump2 = new Hashtable();
- tweDump2.put("show_name", "厂商名称");
- tweDump2.put("col_name", "a4");;
- listTwe.add(tweDump2);
- Hashtable tweDump3 = new Hashtable();
- tweDump3.put("show_name", "厂商性质");
- tweDump3.put("col_name", "a5");;
- listTwe.add(tweDump3);
- Hashtable tweDump4 = new Hashtable();
- tweDump4.put("show_name", "厂商外资国别");
- tweDump4.put("col_name", "a6");;
- listTwe.add(tweDump4);
- Hashtable tweDump5 = new Hashtable();
- tweDump5.put("show_name", "2017年1季度末总数");
- tweDump5.put("col_name", "a7");;
- listTwe.add(tweDump5);
- Hashtable tweDump6 = new Hashtable();
- tweDump6.put("show_name", "2017年2季度新增数量");
- tweDump6.put("col_name", "tbsl");;
- listTwe.add(tweDump6);
- Hashtable tweDump7 = new Hashtable();
- tweDump7.put("show_name", "2017年2季度新增投入金额(万元)");
- tweDump7.put("col_name", "tbje");;
- listTwe.add(tweDump7);
- Hashtable tweDump8 = new Hashtable();
- tweDump8.put("show_name", "备注");
- tweDump8.put("col_name", "a8");;
- listTwe.add(tweDump8);
第三列。这里下面的循环主要是为了报表上 跨行列跨行显示条线,不多解释
- //第三列数据
- Hashtable Tree = new Hashtable();
- Tree.put("show_name", "大类");
- Tree.put("col_name", "");;
- listTree.add(Tree);
- Hashtable Tree1 = new Hashtable();
- Tree1.put("show_name", "小类");
- Tree1.put("col_name", "");;
- for(int i=;i<;i++){
- listTree.add(Tree1);
- }
插入数据:这里需要进行查询数据库操作 。这里我不合并到一起是有原因的。因为每个大类上面有个类别样式
所以我需要这样做判断。
- //插入的数据
- List<Map<String,Object>> listA = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listB = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listC = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listD = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listE = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listF = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listG = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listH = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listI = new ArrayList<Map<String,Object>>();
- List<Map<String,Object>> listJ = new ArrayList<Map<String,Object>>();
- System.out.println("templetid:"+templetid+"--time:"+time);
- //查询数据
- String sql="select t1.*,t2.*,t3.tbjd,t3.tbje,t3.tbsl from (select * from a_templet_safe_control_colnum where templet_id='"+templetid+"' order by A2) t1 left join (select A2,count(*) as counts from a_templet_safe_control_colnum where templet_id='"+templetid+"' group by A2) t2 on t1.A2=t2.A2 left join (select * from a_templet_safe_control_colval where tbjd='"+time+"') t3 on t1.id=t3.templet_num_id where 1=1 ";
- for(int i=;i<;i++){
- Vector var =null;
- switch(i){
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='A' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='B' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='C' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='D' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='E' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='F' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='G' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='H' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='I' ");
- break;
- case :
- var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='J' ");
- break;
- }
- if (var != null && var.size() > ) {
- for (int j = ; j < var.size(); j++) {
- Hashtable ht = (Hashtable) var.get(j);
- switch(i){
- case :
- listA.add(ht);
- break;
- case :
- listB.add(ht);
- break;
- case :
- listC.add(ht);
- break;
- case :
- listD.add(ht);
- break;
- case :
- listE.add(ht);
- break;
- case :
- listF.add(ht);
- break;
- case :
- listG.add(ht);
- break;
- case :
- listH.add(ht);
- break;
- case :
- listI.add(ht);
- break;
- case :
- listJ.add(ht);
- break;
- }
- }
- }
把数据添加到对应的list中
创建表头开始:这里的前三列是固定的可根据自己需求来修改
- //配置显示的固定列数
- int col_num=;
- //创建表头开始
- HSSFRow row0 = sheet.createRow();
- HSSFRow row1 = sheet.createRow();
- HSSFRow row2 = sheet.createRow();
- for(int j=;j<col_num;j++){
- HSSFCellStyle s = getTitleStyle(w,);
- HSSFCell cell0 = row0.createCell(j);
- HSSFCell cell1 = row1.createCell(j);
- HSSFCell cell2 = row1.createCell(j);
- cell0.setCellStyle(s);
- cell1.setCellStyle(s);
- cell2.setCellStyle(s);
- }
- int startCol=;
- for(int i=;i<listOne.size();i++){
- Hashtable ht = (Hashtable)listOne.get(i);
- String group_name = (String)ht.get("group_name");
- int colspan =Integer.parseInt((String)ht.get("col"));
- sheet.getRow().setHeight((short));//设置列高
- HcreateCell(sheet, row0, w, startCol, group_name, , , startCol, (startCol+colspan-),);
- startCol+=colspan;
- }
- startCol=;
- sheet.getRow().setHeight((short));//设置列高
- sheet.getRow().setHeight((short));//设置列高
- for(int i=;i<listTwe.size();i++){
- Hashtable ht = (Hashtable)listTwe.get(i);
- String show_name = (String)ht.get("show_name");
- //System.out.println("i==="+i+"--"+ht.get("show_name"));
- sheet.setColumnWidth((short)i, (short));//设置列宽
- if(i==){
- HcreateCell(sheet, row1, w, startCol, show_name, , , startCol, ,i);
- }else{
- HcreateCell(sheet, row1, w, startCol, show_name, , , startCol, startCol,i);
- }
- startCol++;
- }
- startCol=;
- for(int i=;i<listTree.size();i++){
- Hashtable ht = (Hashtable)listTree.get(i);
- String show_name = (String)ht.get("show_name");
- //System.out.println("i==="+i+"--"+ht.get("show_name"));
- if(i==||i==){
- sheet.setColumnWidth((short)i, (short));//设置列宽
- }
- HcreateCell(sheet, row2, w, startCol, show_name, , , startCol, startCol, i);
- HcreateCell(sheet, row2, w, startCol, show_name, , , startCol, startCol, i);
- startCol++;
- }
- //表头结束
固定值添加完成,开始数据库的值
- //写入数据
- HSSFRow row=null;
- //样式颜色
- HSSFCellStyle s = getCellStyle(w,);
- HSSFCellStyle r = getCellStyle(w,);
- HSSFCellStyle y = getCellStyle(w,);
- HSSFCellStyle g = getCellStyle(w,);
- int rowspan=;
- System.out.println("rowspan==="+rowspan);
- if(listA.size()>){
- for(int j=;j<listA.size()+;j++){
- row =sheet.createRow(j+);
- for(int col=;col<col_num;col++){
- HSSFCell cell = row.createCell(col);
- cell.setCellStyle(s);
- }
- }
- for(int j=;j<listA.size();j++){
- int nums=;
- for(int k=;k<j;k++){
- //System.out.println(listA.get(k).get("a1")+"---"+listA.get(j).get("a1"));
- if(listA.get(k).get("a1").equals(listA.get(j).get("a1"))){
- nums+=;
- }
- }
- if(j==){
- //System.out.println("列高rowspan==="+rowspan);
- sheet.getRow(rowspan).setHeight((short));//设置列高
- createCell(sheet, sheet.getRow(rowspan), w, g, , "A", rowspan, rowspan, , );
- createCell(sheet, sheet.getRow(rowspan), w, g, , "", rowspan, rowspan, , );
- createCell(sheet, sheet.getRow(rowspan), w, g, , "计算机设备", rowspan, rowspan, , );
- createCell(sheet, sheet.getRow(rowspan), w, g, , "", rowspan, rowspan, , );
- rowspan++;
- }
- //System.out.println("列高rowspan==="+rowspan);
- sheet.getRow(rowspan).setHeight((short));//设置列高
- for(int k=;k<listTwe.size();k++){
- //System.out.println("值:"+listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")));
- //第二行
- if(k==){
- //System.out.println("j====="+j+"--"+listA.get(j).get("counts")+"rowspan:"+rowspan+"ID:"+listA.get(j).get("id"));
- createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, (listA.size()+), k, k);
- }else if(k==||k==){
- createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan+Integer.parseInt(listA.get(j).get("counts")+"")-, k, k); //第二列
- }else{
- createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan, k, k);
- }
- }
- rowspan++;
- }
- }
我这里做的判断是 刚进入循环代表循环有值时 打印出类别,
打印类别记得rowspan++操作。因为类别没有在数据库里。如果不做该操作 则会打印时最后一条数据打印不了。因为位置被占了!
然后在进行循环listTwe第二列的数据 这时候刚才定义的col_name用得上了。循环listA的值看哪个能对应col_name则输出!
K==0进行判断 k代表 第几列 第一列要跨当前类的所有行,只打印一次。循环完之后进行rowspan++操作 ,让下次循环知道是第几行的,不会覆盖当前行
一下的listB ...listJ 的类似
最后还有样式:因为需求需要我在定义样式的时候传入值 num 根据num进行打印不同的背景颜色。可根据需求进行调整
- public static HSSFCellStyle getCellStyle(HSSFWorkbook wb,int num) {
- HSSFCellStyle cellStyle = wb.createCellStyle();
- cellStyle.setWrapText(true);
- if(num==){
- cellStyle.setFillForegroundColor(HSSFColor.WHITE.index);
- }else if(num==){
- cellStyle.setFillForegroundColor(HSSFColor.RED.index);
- }else if(num==){
- cellStyle.setFillForegroundColor(HSSFColor.YELLOW.index);
- }else if(num==){
- cellStyle.setFillForegroundColor(HSSFColor.GREEN.index);
- }
- cellStyle.setFillPattern(HSSFCellStyle.BORDER_THIN);
- cellStyle.setBorderBottom((short) );
- cellStyle.setBorderLeft((short) );
- cellStyle.setBorderRight((short) );
- cellStyle.setBorderTop((short) );
- cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
- cellStyle.setBottomBorderColor(HSSFColor.GREY_80_PERCENT.index);
- cellStyle.setLeftBorderColor(HSSFColor.GREY_80_PERCENT.index);
- cellStyle.setRightBorderColor(HSSFColor.GREY_80_PERCENT.index);
- cellStyle.setTopBorderColor(HSSFColor.GREY_80_PERCENT.index);
- cellStyle.setFont(getContentFont(wb,));
- cellStyle.setLocked(false);
- return cellStyle;
- }
打印的字体样式: 根据自己的需求来进行修改。
- public static HSSFFont getContentFont(HSSFWorkbook wb,int i) {
- HSSFFont fontStyle = wb.createFont();
- fontStyle.setFontName("微软雅黑");
- if(i==){
- fontStyle.setFontHeightInPoints((short) );
- }else if(i==){
- fontStyle.setFontHeightInPoints((short) );
- }
- fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
- fontStyle.setColor(HSSFColor.GREY_80_PERCENT.index);
- return fontStyle;
- }
java引用包
- <%@page contentType="text/html; charset=GBK"%>
- <%@page import="java.net.URLEncoder"%>
- <%@page import="java.io.File"%>
- <%@page import="java.io.FileOutputStream"%>
- <%@page import="java.util.*"%>
- <%@page import="java.text.SimpleDateFormat"%>
- <%@page import="java.text.DecimalFormat"%>
- <%@page import="java.math.BigDecimal"%>
- <%@page import="org.apache.poi.hssf.usermodel.*"%>
- <%@page import="org.apache.poi.hssf.util.*"%>
到这,也就完成了导出操作!
有什么不懂得可以一起探讨,有比我更便捷的方法或方式,请告知!
完整代码就不贴了,太多。
转载请注明出处:http://www.cnblogs.com/huole/p/6141814.html
java实现导出Excel(跨行,跨列)的更多相关文章
- 重构:以Java POI 导出EXCEL为例
重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...
- java后端导出excel
最近工作中需要导出excel.这次机智一点做个笔记,顺便写了一个比较通用的工具类.自然目前不能生成java实体类属性嵌套多次的这种没办法导出了,后续有需要的时候我再改改. 首先,java后端导出exc ...
- java 实现导出Excel文件
java 实现导出Excel(java生成 excel 并导出文件) 经常有有一些数据需要导出成 excel 格式 ,所以就需要实现啦 开始: 1.加入jar poi-3.6-20091214. ...
- javascript 将 table 导出 Excel ,可跨行跨列
<script language="JavaScript" type="text/javascript"> //jQuery HTML导出Excel ...
- java:POI导出excel
POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel. 下面是使用示例: 1.maven中先添加依赖项 <dependency> < ...
- Java POI 导出EXCEL经典实现 Java导出Excel
转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...
- java导入导出excel常用操作小结及简单示例
POI中常用设置EXCEL的操作小结: 操作excel如下 HSSFWorkbook wb = new HSSFWorkbook(); //创建一个webbook,对应一个Excel文件 HSSFS ...
- 重构:以Java POI 导出EXCEL为例2
前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...
- 【转载】Java导入导出excel
转自:https://blog.csdn.net/jerehedu/article/details/45195359 目前,比较常用的实现Java导入.导出Excel的技术有两种Jakarta POI ...
随机推荐
- 原生JS实现图片放大镜插件
前 言 我们大家经常逛各种电商类的网站,商品的细节就需要用到放大镜,这个大家一定不陌生,今天我们就做一个图片放大镜的插件,来看看图片是如何被放大的…… 先看一下我们要是实现的最终效果是怎么样的 ...
- ASP.NET Core的身份认证框架IdentityServer4(4)- 支持的规范
IdentityServer实现以下规范: OpenID Connect OpenID Connect Core 1.0 (spec) OpenID Connect Discovery 1.0 (sp ...
- java线程池ThreadPool
package com.java.concurrent; import java.util.concurrent.ExecutorService; import java.util.concurren ...
- AngularJS学习篇(二)
AngularJS 指令 AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 通过内置的指令来为应用添加功能. AngularJS 允许你自定义指令. Angular ...
- G彩娱乐网一个程序员到一个销售高手的心路历程
0.引言 我大学本科读的是理工科,后来毕业以后,我逐渐走上了程 序员的道路.每天面对电脑一行一行的敲代码,这被我们程序员们戏称为"搬砖头",因为我们所做的事跟民工搬砖头砌墙本质上是 ...
- js判断对象为空 JSON.stringify(obj)
JSON.stringify(obj) : 用于从一个对象解析出字符串 var c = {}; if(JSON.stringify(obj) == "{}"){ console.l ...
- [转载] Redis快速入门
转载自http://www.yiibai.com/redis/redis_quick_guide.html Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序 ...
- Linux命令学习备忘
格式: 命令:原理:实践及截图 1.su <user> 执行该命令,需要输入password,它是<user>中定义的用户的password,即,要变换成的用户的passw ...
- Oracle常用的数值函数,日期函数
---恢复内容开始--- 数值函数 常用的处理数值的函数有如下: No. 函数名 含义 1 round(x[,y]) 返回四舍五入后的值 2 trunc(x[,y]) 不会四舍五入 3 mod(x,y ...
- 第二个MapReduce
大家在学习Hadoop的MapReduce的时候,90%的第一个程序都是WordCount,所以在这里分享一下我的第二个MapReduce程序.对于学习编程语言的人来说,有时候代码是最好的沟通方式之一 ...