poi导出Excel报表多表头双层表头、合并单元格

时间:2022-09-21 21:56:01

效果图:

poi导出Excel报表多表头双层表头、合并单元格

controller层方法:

  /**
     * 
     * 导出Excel报表
     * @param request
     * @return
     * 
     */
    @RequestMapping("/export")
    @ResponseBody
    public void export(HttpServletRequest request,
            HttpServletResponse response, String yearMonth) {
        try {
            SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("yearMonth", yearMonth + "%");
            List<TemperHumidityModel> list = temperHumidityService
                    .getList(params);
            for (int i = 0; i < list.size(); i++) {
                Date date = list.get(i).getRecordDate();
                String dateStr = dateFmt.format(date);
                dateStr = dateStr.replace(yearMonth + "-", "");
                list.get(i).setRecordDay(dateStr);
            }
            
            Map<Integer, String> map = new HashMap<Integer, String>();
                map.put(1, "晴");
                map.put(2, "多云");
                map.put(3, "阴");
                map.put(4, "小雨");
                map.put(5, "中雨");
                map.put(6, "大雨");
                map.put(7, "大到暴雨");
                map.put(8, "雾");
                map.put(9, "霾");    
            // 构造导出数据
            List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < list.size(); i++) {
                TemperHumidityModel model = list.get(i);
                Map<String, Object> tmpMap = new HashMap<String, Object>();
                tmpMap.put("date", model.getRecordDay());
                if(model.getWeather() == 1) {
                    tmpMap.put("weather", map.get(1));
                }else if(model.getWeather() == 2) {
                    tmpMap.put("weather", map.get(2));
                }else if(model.getWeather() == 3) {
                    tmpMap.put("weather", map.get(3));
                }else if(model.getWeather() == 4) {
                    tmpMap.put("weather", map.get(4));
                }else if(model.getWeather() == 5) {
                    tmpMap.put("weather", map.get(5));
                }else if(model.getWeather() == 6) {
                    tmpMap.put("weather", map.get(6));
                }else if(model.getWeather() == 7) {
                    tmpMap.put("weather", map.get(7));
                }else if(model.getWeather() == 8) {
                    tmpMap.put("weather", map.get(8));
                }else if(model.getWeather() == 9) {
                    tmpMap.put("weather", map.get(9));
                }
                tmpMap.put("natureTem", model.getNatureTem());
                tmpMap.put("natureHum", model.getNatureHum());
                tmpMap.put("adjustTem", model.getAdjustTem());
                tmpMap.put("adjustHum", model.getAdjustHum());
                tmpMap.put("remark", model.getRemark());
                tmpMap.put("creator", model.getRealname());
                dataList.add(tmpMap);
            }
            String sheetName = "温湿度日记录";
            String date = yearMonth;
            String[] head0 = new String[] { "日期", "天气", "自然", "自然", "调整", "调整",
                    "备注", "记录人" };  //在excel中的第3行每列的参数
            String[] head1 = new String[] { "温度℃", "湿度%", "温度℃", "湿度%" };  //在excel中的第4行每列(合并列)的参数
            String[] headnum0 = new String[] { "2,3,0,0", "2,3,1,1", "2,2,2,3",
                    "2,2,4,5", "2,3,6,6", "2,3,7,7" };  //对应excel中的行和列,下表从0开始{"开始行,结束行,开始列,结束列"}
            String[] headnum1 = new String[] { "3,3,2,2", "3,3,3,3", "3,3,4,4",
                    "3,3,5,5" };
            String[] colName = new String[] { "date", "weather", "natureTem",
                    "natureHum", "adjustTem", "adjustHum", "remark", "creator" };  //需要显示在excel中的参数对应的值,因为是用map存的,放的都是对应的key
            reportMergeXls(request, response, dataList, sheetName, head0,
                    headnum0, head1, headnum1, colName, date);   //utils类需要用到的参数
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

utils类:

package org.base.controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
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.HSSFFont;
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.CellRangeAddress;
import org.base.util.CellUtil;
import org.core.controller.BaseController;

/**
     * 多行表头
     * dataList:导出的数据;sheetName:表头名称; head0:表头第一行列名;headnum0:第一行合并单元格的参数
     * head1:表头第二行列名;headnum1:第二行合并单元格的参数;detail:导出的表体字段
     *
     */
    public void reportMergeXls(HttpServletRequest request,
            HttpServletResponse response, List<Map<String, Object>> dataList,
            String sheetName, String[] head0, String[] headnum0,
            String[] head1, String[] headnum1, String[] detail , String date)
            throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(sheetName);// 创建一个表
        // 表头标题样式
        HSSFFont headfont = workbook.createFont();
        headfont.setFontName("宋体");
        headfont.setFontHeightInPoints((short) 22);// 字体大小
        HSSFCellStyle headstyle = workbook.createCellStyle();
        headstyle.setFont(headfont);
        headstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        headstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        headstyle.setLocked(true);    
        // 表头时间样式
        HSSFFont datefont = workbook.createFont();
        datefont.setFontName("宋体");
        datefont.setFontHeightInPoints((short) 12);// 字体大小
        HSSFCellStyle datestyle = workbook.createCellStyle();
        datestyle.setFont(datefont);
        datestyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        datestyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        datestyle.setLocked(true);
        // 列名样式
        HSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 12);// 字体大小
        HSSFCellStyle style = workbook.createCellStyle();
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        style.setFont(font);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        style.setLocked(true);
        // 普通单元格样式(中文)
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋体");
        font2.setFontHeightInPoints((short) 12);
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        style2.setFont(font2);
        style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        style2.setWrapText(true); // 换行
        style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        // 设置列宽  (第几列,宽度)
        sheet.setColumnWidth( 0, 1600);
        sheet.setColumnWidth( 1, 3600);  
        sheet.setColumnWidth( 2, 2800);  
        sheet.setColumnWidth( 3, 2800);  
        sheet.setColumnWidth( 4, 2800);  
        sheet.setColumnWidth( 5, 2800);
        sheet.setColumnWidth( 6, 4500);
        sheet.setColumnWidth( 7, 3600); 
        sheet.setDefaultRowHeight((short)360);//设置行高
        // 第一行表头标题
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, head0.length-1));
        HSSFRow row = sheet.createRow(0);
        row.setHeight((short) 0x349);
        HSSFCell cell = row.createCell(0);
        cell.setCellStyle(headstyle);
        CellUtil.setCellValue(cell, sheetName);
        // 第二行时间
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, head0.length-1));
        HSSFRow row1 = sheet.createRow(1);
        row.setHeight((short) 0x349);
        HSSFCell cell1 = row1.createCell(0);
        cell1.setCellStyle(datestyle);
        CellUtil.setCellValue(cell1, date);        
        // 第三行表头列名
        row = sheet.createRow(2);
        for (int i = 0; i < 8; i++) {
            cell = row.createCell(i);
            cell.setCellValue(head0[i]);
            cell.setCellStyle(style);
        }
        //动态合并单元格
        for (int i = 0; i < headnum0.length; i++) {
            String[] temp = headnum0[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow,
                    startcol, overcol));
        }
        //设置合并单元格的参数并初始化带边框的表头(这样做可以避免因为合并单元格后有的单元格的边框显示不出来)
        row = sheet.createRow(3);  //因为下标从0开始,所以这里表示的是excel中的第四行
        for (int i = 0; i < head0.length; i++) { 
            cell = row.createCell(i);
            cell.setCellStyle(style);  //设置excel中第四行的1、2、7、8列的边框
            if(i > 1 && i< 6) {
                for (int j = 0; j < head1.length; j++) {
                    cell = row.createCell(j + 2);
                    cell.setCellValue(head1[j]);  //给excel中第四行的3、4、5、6列赋值("温度℃", "湿度%", "温度℃", "湿度%")
                    cell.setCellStyle(style);  //设置excel中第四行的3、4、5、6列的边框
                } 
            } 
        }
        //动态合并单元格
        for (int i = 0; i < headnum1.length; i++) {
            String[] temp = headnum1[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow,
                    startcol, overcol));
        }

// 设置列值-内容
        for (int i = 0; i < dataList.size(); i++) {
            row = sheet.createRow(i + 2 + dataList.size());
            for (int j = 0; j < detail.length; j++) {
                Map tempmap = (HashMap) dataList.get(i);
                Object data = tempmap.get(detail[j]);                
                cell = row.createCell(j);
                cell.setCellStyle(style2);
                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                CellUtil.setCellValue(cell, data);
            }
        }
        String fileName = new String(sheetName.getBytes("gb2312"), "ISO8859-1");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        response.setContentType("application/x-download;charset=utf-8");
        response.addHeader("Content-Disposition", "attachment;filename="
                + fileName + ".xls");
        OutputStream os = response.getOutputStream();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        byte[] b = new byte[1024];
        while ((bais.read(b)) > 0) {
            os.write(b);
        }
        bais.close();
        os.flush();
        os.close();
    }

 
 
 

poi导出Excel报表多表头双层表头、合并单元格的更多相关文章

  1. NPOI&lowbar;winfrom导出Excel表格(一)(合并单元格、规定范围加外边框、存储路径弹框选择)

    1.导出 private void btn_print_Click(object sender, EventArgs e) { DataTable dtNew = new DataTable(); d ...

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

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

  3. apache poi导出excel报表

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为"P ...

  4. POI生成EXCEL文件(字体、样式、单元格合并、计算公式)

    创建一个封装类: package com.jason.excel; import java.io.FileNotFoundException; import java.io.FileOutputStr ...

  5. java&colon;POI导出excel

    POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel. 下面是使用示例: 1.maven中先添加依赖项 <dependency> &lt ...

  6. 【记录】解析具有合并单元格的Excel

    最近公司让做各种数据表格的导入导出,就涉及到电子表格的解析,做了这么多天总结一下心得. 工具:NOPI 语言:C# 目的:因为涉及到导入到数据库,具有合并单元格的多行必然要拆分,而NPOI自动解析的时 ...

  7. 让我头疼一下午的Excel合并单元格

    Excel导出常见问题 excel导出其实不算什么难事 在网上copy下模板代码,填充自己的业务数据,提供一个http接口基本就可以得到你要导出的数据了. 但是,凡事都有例外,截止今天,excel导出 ...

  8. 【开发者笔记】解析具有合并单元格的Excel

    最近公司让做各种数据表格的导入导出,就涉及到电子表格的解析,做了这么多天总结一下心得. 工具:NOPI 语言:C# 目的:因为涉及到导入到数据库,具有合并单元格的多行必然要拆分,而NPOI自动解析的时 ...

  9. C&num; 如何使用NPOI操作Excel以及读取合并单元格等

    C#操作Excel方法有很多,以前用的需要电脑安装office才能用,但因为版权问题公司不允许安装office.所以改用NPOI进行Excel操作,基本上一些简单的Excel操作都没有问题,读写合并单 ...

随机推荐

  1. Apkplug 开发常见问题解答

    Android M (6.0) generatePackageInfo 偶现错误 出现这个现象之后会导致 BundleActivator.start() 方法不会被调用 6.0 方法签名 public ...

  2. C&plus;&plus;以对象管理资源

    先看下面一段代码: class Node {}; Node* CreateNode() { } void Solve() { Node *p=CreateNode(); //调用CreateNode函 ...

  3. C&num; 时间类型

    字符型转换为字符串// C 货币 2.5.ToString("C"); // ¥2.50 // D 10进制数 25.ToString("D5"); // 25 ...

  4. android textview 设置不同的颜色和大小

    1.定义不同的style <style name="approval_detail_info_style1"> <item name="android: ...

  5. CXF WebService 开发文档

    参考资料: 1. http://cxf.apache.org/docs/ 2. http://www.cnblogs.com/hoojo/archive/2011/03/30/1999587.html ...

  6. C&plus;&plus;封装常用对象和对头文件以及预编译机制的探索

    在C++实际开发中,难免会使用到一些你极为常用的算法(比如笔者经常使用的多线程技术),实现这些算法的类或是全局函数或是命名空间等等经常都要被使用多次,你会有哪些办法来使用呢?笔者有4个办法. 第一个方 ...

  7. java交通灯管理系统项目

    交通灯管理系统   模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 异步随机生成按照各个路线行驶的车辆. 例如: 由南向而来去往北向的车辆 ---- 直行车辆 由西向而来去往南向的车辆 ---- ...

  8. Hadoop HDFS &lpar;3&rpar; JAVA訪问HDFS之二 文件分布式读写策略

    先把上节未完毕的部分补全,再剖析一下HDFS读写文件的内部原理 列举文件 FileSystem(org.apache.hadoop.fs.FileSystem)的listStatus()方法能够列出一 ...

  9. 使文字在div中水平和垂直居中的的css样式为,四个边分别设置阴影样式

    text-align:center; /*水平居中*/ line-height: 20px; /*行距设为与div高度一致*/ HTML元素 <div>水平垂直居中</div> ...

  10. git reset的用法

    git reset三个选项 --mix,--hard,--soft 数据 针对每个选项都是操作这个文件. [root@centos demo]# git init Initialized empty ...