java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体;另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是把数据封装到List<Map<String,Object>>,如果数据中还有分支,那么继续把数据封装到List<Map<String,Object>>中去。

主要说说复杂数据类型的导出,复杂类型的导出,就是合并单元格,单元格合并也分合并行,合并列。

1. 代码中的

sheet.addMergedRegion(new Region(0, (short)i, 2, (short)i)); 合并行

合并的是第一行的第 i列,都占三行。 为1、2、3、4 然后第三个参数是合并3行。行和列的坐标都是从0开始的

sheet.addMergedRegion(new Region(1, (short)start, 1, (short)(end)));  合并列  合并的是第二行(第一个参数是1)的低start列到end列。

Region 对象中有4个参数:起始行、起始列、结束行、结束列

我的查询出来的数据结构:

{
    questionnaireName=问卷00, questionSize=3, firstDepart=办公室, joinPersons=1, secondDepart=综合管理科,
    questions=[
        {questionName=问题1, answers=[
            {optionId=8ae0940555b484fd0155b488b6aa0003, questionId=8ae0940555b484fd0155b488b6aa0002, value=选项1, statistical=[100, 1]},
            {optionId=8ae0940555b484fd0155b488b6ab0004, questionId=8ae0940555b484fd0155b488b6aa0002, value=选项2, statistical=[0, 0]},
            {optionId=8ae0940555b484fd0155b488b6ab0005, questionId=8ae0940555b484fd0155b488b6aa0002, value=选项3, statistical=[0, 0]}
        ], selectType=1},
        {questionName=问题2, answers=[
            {optionId=8ae0940555b484fd0155b488b6ab0007, questionId=8ae0940555b484fd0155b488b6ab0006, value=答案1, statistical=[0, 0]},
            {optionId=8ae0940555b484fd0155b488b6ab0008, questionId=8ae0940555b484fd0155b488b6ab0006, value=答案2, statistical=[100, 1]},
            {optionId=8ae0940555b9d72d0155b9f512940001, questionId=8ae0940555b484fd0155b488b6ab0006, value=答案3, statistical=[100, 1]},
            {optionId=8ae0940555b9d72d0155b9f512a00002, questionId=8ae0940555b484fd0155b488b6ab0006, value=答案4, statistical=[100, 1]}
        ], selectType=2},
        {questionName=问题3, answers=[
            {optionId=8ae0940555e8520c0155e9c3c5330001, questionId=8ae0940555b484fd0155b488b6ac0009, value=答案1, statistical=[0, 0]},
            {optionId=8ae0940555e8520c0155e9c3c5410002, questionId=8ae0940555b484fd0155b488b6ac0009, value=答案2, statistical=[100, 1]},
            {optionId=8ae0940555e8520c0155e9c3c5410003, questionId=8ae0940555b484fd0155b488b6ac0009, value=答案3, statistical=[0, 0]}, {
            optionId=8ae0940555e8520c0155e9c3c5410004, questionId=8ae0940555b484fd0155b488b6ac0009, value=答案4, statistical=[0, 0]
        }], selectType=1}
    ]}

一.复杂数据类型导出

package com.moses.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
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.HSSFRichTextString;
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.Region;

public class ExportExcel<T>  
{  
    @SuppressWarnings({"deprecation", "unchecked" })  
    public static void exportExcel(String title,Map<String,Object> result, OutputStream out) throws IOException  
    {  
        // 声明一个工作薄  
        HSSFWorkbook workbook = new HSSFWorkbook();  
//        //设置表格样式
//        HSSFCellStyle style = workbook.createCellStyle();
//        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 居中
//        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//        //设置字体
//        HSSFFont font = workbook.createFont();  
//        font.setFontName("黑体");  
//        font.setFontHeightInPoints((short) 16);
        
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        HSSFRow row = sheet.createRow(0);
        HSSFRow row1 = sheet.createRow(1);
        HSSFRow row2 = sheet.createRow(2);
        HSSFRow row3 = sheet.createRow(3);
        for (int i = 0; i < result.size()-1; i++) {
            HSSFCell cell = row.createCell((short)i);
            if(i==0){
                sheet.addMergedRegion(new Region(0, (short)i, 2, (short)i));
                cell.setCellValue(new HSSFRichTextString("问卷名称"));
                //第二行的第一列赋值
                HSSFCell row1cell0 = row3.createCell((short)0);
                row1cell0.setCellValue(new HSSFRichTextString((String)result.get("questionnaireName")));
            }else if(i==1){
                sheet.addMergedRegion(new Region(0, (short)i, 2, (short)i));
                cell.setCellValue(new HSSFRichTextString("答卷人数"));
                //第二行的第二列赋值
                HSSFCell row1cell1 = row3.createCell(1);
                row1cell1.setCellValue(new HSSFRichTextString(String.valueOf(result.get("joinPersons"))));
            }else if(i==2){
                sheet.addMergedRegion(new Region(0, (short)i, 2, (short)i));
                cell.setCellValue(new HSSFRichTextString("一级部门"));
                //第二行的第三列赋值
                HSSFCell row1cell2 = row3.createCell(i);
                row1cell2.setCellValue(new HSSFRichTextString((String)result.get("firstDepart")));
            }else if(i==3){
                sheet.addMergedRegion(new Region(0, (short)i, 2, (short)i));
                cell.setCellValue(new HSSFRichTextString("二级部门"));
                //第二行的第四列赋值
                HSSFCell row1cell3 = row3.createCell(i);
                row1cell3.setCellValue(new HSSFRichTextString((String)result.get("secondDepart")));
            }else{
                //获取该问卷所有的问题
                List<Map<String,Object>> questionNames = (List<Map<String,Object>>)result.get("questions");
                int b = 0;
                int m = 0;
                for (int j = 0; j < questionNames.size(); j++) {
                    //4
                    m = i+j+b; //m为列的坐标
                    HSSFCell cell1 = row.createCell((short)(m));
                    //获取当前问题的答案
                    List<Map<String,Object>> answers = (List<Map<String,Object>>)questionNames.get(j).get("answers");
                    String selectType = (String)questionNames.get(j).get("selectType");
                    System.out.println("selectType:"+selectType);
                    if("2".equals(selectType)|| "1".equals(selectType)){
                        //答案
                        for (int k = 0; k < answers.size(); k++) {
                            //第二行显示答案:起始位置:m+2*k,结束位置:m+2*k+1
                            int start = m+2*k; //0:4,1:6,2:8
                            int end = m+2*k+1; //0:5,1:7,2:9
                            HSSFCell cell2 = row1.createCell((short)(start));
                            sheet.addMergedRegion(new Region(1, (short)start, 1, (short)(end)));
                            cell2.setCellValue((String)answers.get(k).get("value"));
                            //第三行显示标题性文字:比例,人员
                            HSSFCell cell3 = row2.createCell((short)(start));
                            HSSFCell cell4 = row2.createCell((short)(end));
                            cell3.setCellValue("比例");
                            cell4.setCellValue("人数");
                            //第四行显示查询出来的比例和人数的数据
                            HSSFCell cell5 = row3.createCell((short)(start));
                            HSSFCell cell6 = row3.createCell((short)(end));
                            List<String> statistical = (List<String>)answers.get(k).get("statistical");
                            cell5.setCellValue(statistical.get(0)+"%");    //比例
                            cell6.setCellValue(statistical.get(1));    //人数
                        }
                    }
                    //问题
                    b = m+2*answers.size();
                    sheet.addMergedRegion(new Region(0, (short)m, 0, (short)(b-1)));
                    cell1.setCellValue((String)questionNames.get(j).get("questionName"));
                    b = b-i-j-1;
                }
            }
        }
        workbook.write(out);
    }
}

结果:

二、依赖实体的导出

package com.moses.util;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFComment;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.HSSFColor;
 
/**
 * 利用开源组件POI3.0.2动态导出EXCEL文档 转载时请保留以下信息,注明出处!
 *            应用泛型,代表任意一个符合javabean风格的类
 *            注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
 *            byte[]表jpg格式的图片数据
 */  
public class ExportUtil<T>  
{  
    /**
     * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
     *  
     * @param    title    表格标题名
     * @param    headers 表格属性列名数组
     * @param    dataset 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
     *          javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
     * @param    parmas    实体类中的属性
     * @param    out        与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
     * @param    pattern    如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
     */  
    @SuppressWarnings({ "unchecked", "deprecation" })  
    public  void exportExcel(String title, String[] headers,Collection<T> dataset,String[]params, OutputStream out)  
    {  
        // 声明一个工作薄  
        HSSFWorkbook workbook = new HSSFWorkbook();  
        // 生成一个表格  
        HSSFSheet sheet = workbook.createSheet(title);  
        // 设置表格默认列宽度为15个字节  
        sheet.setDefaultColumnWidth((short) 15);  
        // 生成一个样式  
        HSSFCellStyle style = workbook.createCellStyle();  
        // 设置这些样式  
        style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);  
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);  
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);  
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);  
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);  
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
        // 生成一个字体  
        HSSFFont font = workbook.createFont();  
        font.setColor(HSSFColor.VIOLET.index);  
        font.setFontHeightInPoints((short) 12);  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        // 把字体应用到当前的样式  
        style.setFont(font);  
        // 生成并设置另一个样式  
        HSSFCellStyle style2 = workbook.createCellStyle();  
        style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);  
        style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);  
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);  
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);  
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);  
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);  
        style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
        style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);  
        // 生成另一个字体  
        HSSFFont font2 = workbook.createFont();  
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);  
        // 把字体应用到当前的样式  
        style2.setFont(font2);  
 
        // 声明一个画图的顶级管理器  
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();  
        // 定义注释的大小和位置,详见文档  
        HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));  
        // 设置注释内容  
        comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));  
        // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.  
        comment.setAuthor("leno");  
 
        // 产生表格标题行  
        HSSFRow row = sheet.createRow(0);  
        for (short i = 0; i < headers.length; i++)  
        {  
            HSSFCell cell = row.createCell(i);  
            cell.setCellStyle(style);  
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);  
            cell.setCellValue(text);  
        }  
        // 遍历集合数据,产生数据行  
        Iterator<T> it = dataset.iterator();  
        int index = 0;  
        while (it.hasNext())  
        {  
            index++;  
            row = sheet.createRow(index);  
            T t = (T) it.next();  
            for (short i = 0; i < params.length; i++)  
            {  
                HSSFCell cell = row.createCell(i);  
                cell.setCellStyle(style2);  
                String getMethodName = "get" + params[i];
                try  
                {  
                    Class tCls = t.getClass();  
                    Method getMethod = tCls.getMethod(getMethodName,new Class[]{});  
                    Object value = getMethod.invoke(t, new Object[] {});  
                    // 判断值的类型后进行强制类型转换   其它数据类型都当作字符串简单处理
                    String textValue = value.toString();  
                    // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成  
                    if (textValue != null) {  
                        Pattern p = Pattern.compile("^//d+(//.//d+)?$");  
                        Matcher matcher = p.matcher(textValue);  
                        if (matcher.matches()){  
                            // 是数字当作double处理  
                            cell.setCellValue(Double.parseDouble(textValue));  
                        }else{  
                            HSSFRichTextString richString = new HSSFRichTextString(  
                                    textValue);  
                            HSSFFont font3 = workbook.createFont();  
                            font3.setColor(HSSFColor.BLUE.index);  
                            richString.applyFont(font3);  
                            cell.setCellValue(richString);  
                        }  
                    }  
                }catch (SecurityException e){  
                    e.printStackTrace();  
                }catch (NoSuchMethodException e){  
                    e.printStackTrace();  
                }catch (IllegalArgumentException e){  
                    e.printStackTrace();  
                }catch (IllegalAccessException e){  
                    e.printStackTrace();  
                }catch (InvocationTargetException e){  
                    e.printStackTrace();  
                }
            }  
        }  
        try{  
            workbook.write(out);  
        }catch (IOException e){  
            e.printStackTrace();  
        }
    }  
 
//    public static void main(String[] args)  
//    {  
//        // 测试学生  
//          ExportUtil<Student> ex = new ExportUtil<Student>();  
//        String[] headers = { "学号", "姓名", "年龄", "性别", "出生日期" };  
//        List<Student> dataset = new ArrayList<Student>();  
//        dataset.add(new Student(10000001, "张三", 20, true, new Date()));  
//        dataset.add(new Student(20000002, "李四", 24, false, new Date()));  
//        dataset.add(new Student(30000003, "王五", 22, true, new Date()));  
//        try  
//        {  
//            OutputStream out = new FileOutputStream("/Users/meixiaolong/work-mxl/1.xls");  
//            ex.exportExcel(headers, dataset, out);  
//            out.close();  
//            JOptionPane.showMessageDialog(null, "导出成功!");  
//            System.out.println("excel导出成功!");  
//        }  
//        catch (FileNotFoundException e)  
//        {  
//            e.printStackTrace();  
//        }  
//        catch (IOException e)  
//        {  
//            e.printStackTrace();  
//        }  
//    }  
}

java poi导出excel,合并单元格相关推荐

  1. java POI导出excel,合并单元格边框消失

    业务是导出一个报表,要求有一个跨多列的表头,肯定要用到合并单元格,但合并后边框消失.网上的一些解决办法是重写合并单元格方法,但弄清楚原因后,其实没必要. 原来是这样的: 合并后就第一个有边框,其余全成 ...

  2. Java POI 对Excel合并单元格的数据处理

    Java POI 对Excel合并单元格的数据处理 最近在项目开发过程中,有个一个导入Excel文件处理合并单元格数据的需求,就自己在网上找了一个模板,自己进行二次开发来开发需求. Excel工具类 ...

  3. POI导出EXCEL合并单元格对象嵌套List数据

    导出EXCEL 在实际的开发过程当中,我们会遇到一些比较复杂的导出需求,例如需要导出的实体类中需要嵌套集合对象等,正好最近碰到了所以分享出来,希望对大家有帮助 一.POI是什么 简单的说就是Apach ...

  4. java SXSSF 导出excel 合并单元格,设置打印分页

    官方poi地址: Busy Developers' Guide to HSSF and XSSF Features HSSFWorkbook.XSSFWorkbook.SXSSFWorkbook的区别 ...

  5. poi导出Excel合并单元格、设置打印参数页眉页脚等

    由于生成文件不能落地,使用SXSSFWorkBook来对excel的导出工作 生成excel步骤: 1.创建workbook SXSSFWorkbook workbook=new SXSSFWorkb ...

  6. poi导出excel合并单元格

    /*导出服务*/@RequestMapping(value = "/exportMaintenance.html")public void exportMaintenance(Ht ...

  7. springboot项目导出excel 合并单元格表格

    springboot项目导出excel 合并单元格表格 导出效果 业务controller 业务数据 业务实体类 注解MyExcel.java 注解 MyExcels 导出工具类MyExcelUtil ...

  8. POI导出Excel设置单元格背景色

    POI导出Excel设置单元格背景色 导出Excel的时候,没有设置背景色,用2003版本的Excel工具打开会出现文档单元格背景自动填充黑色的情况,没有找到好的解决方法,就主动给他填充一种颜色,问题 ...

  9. POI导出——Excel实现单元格的背景色填充

    1.背景 随着业务需求的扩充,简简单单的Excel导出已经不能满足客户的胃口了.而POI api这个家伙里面的坑有时候真的是让你分分钟没有脾气,所以打算记录下来,分享一下poi的坑及其解决方法. 2. ...

  10. java导出excel合并单元格

    今天是2018最后一天了,废话就不多说了直接上干货吧! 1.java导出excel用到POI所有jar包 ,大家可以直接到下面地址下载点击打开链接 2.导出excel的方法 package org; ...

最新文章

  1. Python | 新手必会的 9 个 Python 技巧
  2. 天津理工大学c语言上机报告3,天津理工大学-c语言上机报告4.pdf
  3. kafka一直rebalance故障,重复消费
  4. mysql分页查询关键_MySQL优化教程之超大分页查询
  5. C#序列化和反序列化代码总结
  6. java 指针 引用_java中的引用与c中的指针
  7. 深度学习笔记(23) 卷积维度
  8. win下mysql数据库双机配置_[数据库]windows下使用mysql双机热备功能
  9. python中按照文件夹中文件的排列顺序读取文件内容
  10. UIWebView关于XMLHttpRequest的内存泄漏
  11. Linux Web基础
  12. 基于Android的小巫新闻客户端开发系列教程
  13. 视频显示器与服务器之间使用什么线连接,显示器连接线有哪些?四种主流连线科普。...
  14. 破解版editPlus
  15. 仓库管理(WMS)系统及其组成
  16. IDEA编译错误PersistentEnumerator storage corrupted
  17. TSL SSL SSH Openssl Openssh 区别
  18. 链表逆置(三种方法详解)
  19. Dynamo For Revit: List 连缀 和 Level
  20. *PAT_甲级_1072 Gas Station (30point(s)) (C++)【Dijkstra/字符串截取/与数字相互转换】

热门文章

  1. 领导看了会炸毛的溢出理论
  2. C++ abort() has been called错误
  3. 循环冗余校验码CRC原理和实例
  4. 知意配音和讯飞配音哪个好用点?这是一篇对比文
  5. Android Systrace 基础知识(10) - Binder 和锁竞争解读
  6. 南京航空航天大学矩阵论答案
  7. TCP/IP原理、基础以及在Linux上的实现
  8. 什么是overlay?
  9. python 调用Google Translate API进行翻译
  10. 乌丹一中2021高考成绩查询,2021年赤峰高考状元名单公布,赤峰文理科状元是谁多少分...