码迷,mamicode.com
首页 > 编程语言 > 详细

java通过poi导出excel

时间:2021-02-26 13:02:40      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:urlencode   依赖   图片   alt   jar   variable   get   exp   集中   

PS:这几天项目中用到poi导出数据至excel,这里将poi导出excel再回忆下。

一、创建空的springboot项目,在pom文件中加入操作Excel所需要的jar

<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>3.15</version>
</dependency>

此处注意 org.apache.poi下有很多依赖包,我们选择我们此次操作excel(.xls、.XLSX)所需要的依赖,选择poi-ooxml即可。

此处附上官网说明(http://poi.apache.org/components/

技术图片

 

二、工具类

 在POI中操作Excel大致分为两种,2003版本和2007版本及以上,前者最大支持65536行,后者最大支持1048576行,两种所使用的工具类是不一样的(例如03使用HSSFWorkbook,07使用XSSFWorkbook)。

2003版的最大不能超过65535行,2007版没测出来,内存溢出了

技术图片

 1、 2007版工具方法(无或者只有1行标题)

     /**
     *@Description:03版后缀.xls,标题可有可无,如无标题则headers传null即可
     *@Param: title excel名称,也可当sheet页名称使用
     *@Param: headers 标题
     *@Param: dataset 数据集
     *@Param: out 输出流
     *@Param: dataset 数据集,此处必须为Map
     *@Param: pattern 如果表格中有时间类型按照这种格式展示
     *@Param: keys 数据集中Map的字段名称
     *@return:void
     *@Author: 张江坤
     *@date: 2021/2/24 21:54
     */
    public static void exportExcel2003(String title, String[] headers, List<Map<String,Object>> dataset, OutputStream out, String pattern,List<String> keys) {
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(20);
        // 生成一个样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.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.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("宋体");
        font.setColor(HSSFColor.WHITE.index);
        font.setFontHeightInPoints((short) 11);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setFillForegroundColor(HSSFColor.WHITE.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);
        HSSFRow row;
        //有无标题,适应于标题在数据集中
        if(null != headers){
            // 产生表格标题行
            row = sheet.createRow(0);
            HSSFCell cellHeader;
            for (int i = 0;i < headers.length; i++) {
                cellHeader = row.createCell(i);
                cellHeader.setCellStyle(style);
                cellHeader.setCellValue(new HSSFRichTextString(headers[i]));
            }
        }
        if(!dataset.isEmpty()) {
            // 遍历集合数据,产生数据行
            Iterator<Map<String,Object>> it = dataset.iterator();
            //如果没有标题,则从第0行开始写数据
            int index = null==headers ? -1 : 0;
            Map<String,Object> t;
            Field field;
            HSSFRichTextString richString;
            Pattern p = Pattern.compile("^//d+(//.//d+)?$");
            Matcher matcher;
            HSSFCell cell;
            Object value;
            String textValue;
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            while (it.hasNext()) {
                index++;
                row = sheet.createRow(index);
                t = (Map<String,Object>) it.next();

                for (int i = 0; i < keys.size(); i++) {
                    cell = row.createCell(i);
                    cell.setCellStyle(style2);
                    try {
                        value = t.get(keys.get(i));
                        // 判断值的类型后进行强制类型转换
                        textValue = null;
                        if (value instanceof Integer) {
                            cell.setCellValue((Integer) value);
                        } else if (value instanceof Float) {
                            textValue = String.valueOf((Float) value);
                            cell.setCellValue(textValue);
                        } else if (value instanceof Double) {
                            textValue = String.valueOf((Double) value);
                            cell.setCellValue(textValue);
                        } else if (value instanceof Long) {
                            cell.setCellValue((Long) value);
                        }
                        if (value instanceof Boolean) {
                            textValue = "是";
                            if (!(Boolean) value) {
                                textValue = "否";
                            }
                        } else if (value instanceof Date) {
                            textValue = sdf.format((Date) value);
                        } else {
                            // 其它数据类型都当作字符串简单处理
                            if (value != null) {
                                textValue = value.toString();
                            }
                        }
                        if (textValue != null) {
                            matcher = p.matcher(textValue);
                            if (matcher.matches()) {
                                // 是数字当作double处理
                                cell.setCellValue(Double.parseDouble(textValue));
                            } else {
                                richString = new HSSFRichTextString(textValue);
                                cell.setCellValue(richString);
                            }
                        }
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } finally {
                        // 清理资源
                    }
                }
            }
        }

        try {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 2、2007版工具方法(无或者只有1行标题,较2003版,更替了工具类,逻辑一样,粘贴此处方便使用)

   /**
     *@Description:07版后缀.xlsx,标题可有可无,如无标题则headers传null即可
     *@Param: title excel名称,也可当sheet页名称使用
     *@Param: headers 标题
     *@Param: dataset 数据集
     *@Param: out 输出流
     *@Param: dataset 数据集,此处必须为Map
     *@Param: pattern 如果表格中有时间类型按照这种格式展示
     *@Param: keys 数据集中Map的字段名称
     *@return:void
     *@Author: 张江坤
     *@date: 2021/2/24 21:54
     */
    public static void exportExcel2007(String title, String[] headers, List<Map<String,Object>> dataset, OutputStream out, String pattern,List<String> keys) {
        // 声明一个工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 生成一个表格
        XSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(20);
        // 生成一个样式
        XSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setFillForegroundColor(new XSSFColor(Color.gray));
        style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        style.setBorderRight(XSSFCellStyle.BORDER_THIN);
        style.setBorderTop(XSSFCellStyle.BORDER_THIN);
        style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        // 生成一个字体
        XSSFFont font = workbook.createFont();
        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("宋体");
        font.setColor(new XSSFColor(Color.BLACK));
        font.setFontHeightInPoints((short) 11);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        XSSFCellStyle style2 = workbook.createCellStyle();
        style2.setFillForegroundColor(new XSSFColor(Color.WHITE));
        style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
        style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        // 生成另一个字体
        XSSFFont font2 = workbook.createFont();
        font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
        // 把字体应用到当前的样式
        style2.setFont(font2);
        XSSFRow row;
        //有无标题,取决于标题是否在数据集中
        if(null != headers){
            // 产生表格标题行
            row = sheet.createRow(0);
            XSSFCell cellHeader;
            for (int i = 0;i < headers.length; i++) {
                cellHeader = row.createCell(i);
                cellHeader.setCellStyle(style);
                cellHeader.setCellValue(new XSSFRichTextString(headers[i]));
            }
        }
        if(!dataset.isEmpty()) {
            // 遍历集合数据,产生数据行
            Iterator<Map<String,Object>> it = dataset.iterator();
            //如果没有标题,则从第0行开始写数据
            int index = null==headers ? -1 : 0;
            Map<String,Object> t;
            Field field;
            XSSFRichTextString richString;
            Pattern p = Pattern.compile("^//d+(//.//d+)?$");
            Matcher matcher;
            XSSFCell cell;
            Object value;
            String textValue;
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            while (it.hasNext()) {
                index++;
                row = sheet.createRow(index);
                t = (Map<String,Object>) it.next();

                for (int i = 0; i < keys.size(); i++) {
                    cell = row.createCell(i);
                    cell.setCellStyle(style2);
                    try {
                        value = t.get(keys.get(i));
                        // 判断值的类型后进行强制类型转换
                        textValue = null;
                        if (value instanceof Integer) {
                            cell.setCellValue((Integer) value);
                        } else if (value instanceof Float) {
                            textValue = String.valueOf((Float) value);
                            cell.setCellValue(textValue);
                        } else if (value instanceof Double) {
                            textValue = String.valueOf((Double) value);
                            cell.setCellValue(textValue);
                        } else if (value instanceof Long) {
                            cell.setCellValue((Long) value);
                        }
                        if (value instanceof Boolean) {
                            textValue = "是";
                            if (!(Boolean) value) {
                                textValue = "否";
                            }
                        } else if (value instanceof Date) {
                            textValue = sdf.format((Date) value);
                        } else {
                            // 其它数据类型都当作字符串简单处理
                            if (value != null) {
                                textValue = value.toString();
                            }
                        }
                        if (textValue != null) {
                            matcher = p.matcher(textValue);
                            if (matcher.matches()) {
                                // 是数字当作double处理
                                cell.setCellValue(Double.parseDouble(textValue));
                            } else {
                                richString = new XSSFRichTextString(textValue);
                                cell.setCellValue(richString);
                            }
                        }
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } finally {
                        // 清理资源
                    }
                }
            }
        }
        try {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

调用入口

public void exportExcle(@PathVariable("fileName") String fileName, HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        try {
            response.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8") + ".xls");//03版后缀为.xls 07版后缀为.xlsx
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        List<Map<String,Object>> list = new ArrayList<>();
        for(int i=0;i<65535;i++){
            Map<String,Object> map = new HashMap<>();
            map.put("one","第"+(i+1)+"列的值");
            map.put("two","第"+(i+1)+"列的值");
            map.put("three","第"+(i+1)+"列的值");
            map.put("four","第"+(i+1)+"列的值");
            map.put("five","第"+(i+1)+"列的值");
            map.put("six","第"+(i+1)+"列的值");
            list.add(map);
        }
     //生成的excel中的列名 String[] header
= {"第1列","第2列","第3列","第4列","第5列","第6列"};
     //数据集中对应的key List
<String> keys = Arrays.asList("one","two","three","four","five","six"); try { ExportExcelUtil.exportExcel2003(fileName, header, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys); //ExportExcelUtil.exportExcel2007(fileName, null, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys); } catch (IOException e) { e.printStackTrace(); } }

无标题截图

技术图片

有标题截图

技术图片

3、03版标题合并类型工具方法

/**
     *@Description:03版 .xls
     *@Param: title excel名称,也可当sheet页名称使用
     *@Param: headers_1 未合并的第一部分标题
     *@Param: headers_2 合并单元格的大标题
     *@Param: headers_3 不合并的第二部分列名
     *@Param: headers_4 合并单元格的小标题
     *@Param: nums 合并列中每大列占几小列,例如 [3,3]第1,2大列各占3小列
     *@Param: keys 数据集中Map的字段名称
     *@Param: dataset 数据集,此处必须为Map
     *@Param: out 输出流
     *@Param: pattern 如果表格中有时间类型按照这种格式展示
     *@return:void
     *@Author: 张江坤
     *@date: 2021/2/23 13:48
     */
    public static void exportExcel2003(String title, String[] headers_1,String[] headers_2,String[] headers_3, String[] headers_4, int[] nums, List<Map<String,Object>> dataset, List<String> keys, OutputStream out, String pattern) {

        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(20);
        // 生成一个样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.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.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("宋体");
        font.setColor(HSSFColor.WHITE.index);
        font.setFontHeightInPoints((short) 11);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setFillForegroundColor(HSSFColor.WHITE.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);

        HSSFRow row = sheet.createRow(0);
        //设置未合并的第一部分列的格式
        for(int i=0; i<headers_1.length; i++){
            //占2行1列(因为有合并行,合并列)
            CellRangeAddress cra=new CellRangeAddress(0, 1, i, i);
            sheet.addMergedRegion(cra);
        }
        //为未合并行的第一部分列写入标题
        for(int i=0; i<headers_1.length; i++){
            final Cell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_1[i]);
        }
        int sum1 = 0;
        int sum2 = 0;
        //合并列的大标题
        for(int i=0; i<headers_2.length; i++){//受理数,办结数
            sum1 += nums[i];
            //占1行,从header_2长度后的那列开始数,画够合并行的宽度
            CellRangeAddress cra=new CellRangeAddress(0, 0, headers_1.length+sum2, headers_1.length+sum1-1);
            sheet.addMergedRegion(cra);
            sum2 += nums[i];
        }
        int sum = 0;
        for(int i=0; i<headers_2.length; i++){
            //给合并列中的大列写入标题,未合并列第一部分宽度 + 合并列各列中小列的宽度
            final Cell cell = row.createCell(headers_1.length+sum);
            cell.setCellStyle(style);
            cell.setCellValue(headers_2[i]);
            sum += nums[i];
        }

        //未合并列的第二部分列设置格式,占2行1列
        for(int i=0; i<headers_3.length; i++){
            CellRangeAddress cra=new CellRangeAddress(0, 1, headers_1.length+sum2+i, headers_2.length+sum2+i);
            sheet.addMergedRegion(cra);
        }
        //给未合并列的第二部分列写入标题
        for(int i=0; i<headers_3.length; i++){
            final Cell cell = row.createCell(headers_1.length+sum2+i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_3[i]);
        }
        //重新创建一行,写入合并列中的小列
        row = sheet.createRow(1);
        for(int i=0; i<headers_4.length; i++){
            final Cell cell = row.createCell(headers_1.length+i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_4[i]);
        }

        // 遍历集合数据,产生数据行
        Iterator<Map<String,Object>> it = dataset.iterator();
        int index = 1;
        Map<String,Object> t;
        HSSFRichTextString richString;
        Pattern p = Pattern.compile("^//d+(//.//d+)?$");
        Matcher matcher;
        HSSFCell cell;
        Object value;
        String textValue;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            t = (Map<String,Object>) it.next();
            for (int i = 0; i < keys.size(); i++) {
                cell = row.createCell(i);
                cell.setCellStyle(style2);
                try {
                    value = t.get(keys.get(i));
                    // 判断值的类型后进行强制类型转换
                    textValue = null;
                    if (value instanceof Integer) {
                        cell.setCellValue((Integer) value);
                    } else if (value instanceof Float) {
                        textValue = String.valueOf((Float) value);
                        cell.setCellValue(textValue);
                    } else if (value instanceof Double) {
                        textValue = String.valueOf((Double) value);
                        cell.setCellValue(textValue);
                    } else if (value instanceof Long) {
                        cell.setCellValue((Long) value);
                    }
                    if (value instanceof Boolean) {
                        textValue = "是";
                        if (!(Boolean) value) {
                            textValue = "否";
                        }
                    } else if (value instanceof Date) {
                        textValue = sdf.format((Date) value);
                    } else {
                        // 其它数据类型都当作字符串简单处理
                        if (value != null) {
                            textValue = value.toString();
                        }
                    }
                    if (textValue != null) {
                        matcher = p.matcher(textValue);
                        if (matcher.matches()) {
                            // 是数字当作double处理
                            cell.setCellValue(Double.parseDouble(textValue));
                        } else {
                            richString = new HSSFRichTextString(textValue);
                            cell.setCellValue(richString);
                        }
                    }
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } finally {
                    // 清理资源
                }
            }
        }
        try {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4、07版标题合并类型工具方法

    /**
     *@Description:07版 .xlsx
     *@Param: title excel名称,也可当sheet页名称使用
     *@Param: headers_1 未合并的第一部分标题
     *@Param: headers_2 合并单元格的大标题
     *@Param: headers_3 不合并的第二部分列名
     *@Param: headers_4 合并单元格的小标题
     *@Param: nums 合并列中每大列占几小列,例如 [3,3]第1,2大列各占3小列
     *@Param: keys 数据集中Map的字段名称
     *@Param: dataset 数据集,此处必须为Map
     *@Param: out 输出流
     *@Param: pattern 如果表格中有时间类型按照这种格式展示
     *@return:void
     *@Author: 张江坤
     *@date: 2021/2/23 13:48
     */
    public static void exportExcel2007(String title, String[] headers_1,String[] headers_2,String[] headers_3, String[] headers_4, int[] nums, List<Map<String,Object>> dataset, List<String> keys, OutputStream out, String pattern) {

        // 声明一个工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 生成一个表格
        XSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(20);
        // 生成一个样式
        XSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setFillForegroundColor(new XSSFColor(Color.gray));
        style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        style.setBorderRight(XSSFCellStyle.BORDER_THIN);
        style.setBorderTop(XSSFCellStyle.BORDER_THIN);
        style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        // 生成一个字体
        XSSFFont font = workbook.createFont();
        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("宋体");
        font.setColor(new XSSFColor(Color.BLACK));
        font.setFontHeightInPoints((short) 11);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        XSSFCellStyle style2 = workbook.createCellStyle();
        style2.setFillForegroundColor(new XSSFColor(Color.WHITE));
        style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
        style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        // 生成另一个字体(标题跟正文分开)
        XSSFFont font2 = workbook.createFont();
        font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
        // 把字体应用到当前的样式
        style2.setFont(font2);

        XSSFRow row = sheet.createRow(0);
        //设置未合并的第一部分列的格式
        for(int i=0; i<headers_1.length; i++){
            //占2行1列(因为有合并行,合并列)
            CellRangeAddress cra=new CellRangeAddress(0, 1, i, i);
            sheet.addMergedRegion(cra);
        }
        //为未合并行的第一部分列写入标题
        for(int i=0; i<headers_1.length; i++){
            final Cell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_1[i]);
        }
        int sum1 = 0;
        int sum2 = 0;
        //合并列的大标题
        for(int i=0; i<headers_2.length; i++){//受理数,办结数
            sum1 += nums[i];
            //占1行,从header_2长度后的那列开始数,画够合并行的宽度
            CellRangeAddress cra=new CellRangeAddress(0, 0, headers_1.length+sum2, headers_1.length+sum1-1);
            sheet.addMergedRegion(cra);
            sum2 += nums[i];
        }
        int sum = 0;
        for(int i=0; i<headers_2.length; i++){
            //给合并列中的大列写入标题,未合并列第一部分宽度 + 合并列各列中小列的宽度
            final Cell cell = row.createCell(headers_1.length+sum);
            cell.setCellStyle(style);
            cell.setCellValue(headers_2[i]);
            sum += nums[i];
        }

        //未合并列的第二部分列设置格式,占2行1列
        for(int i=0; i<headers_3.length; i++){
            CellRangeAddress cra=new CellRangeAddress(0, 1, headers_1.length+sum2+i, headers_2.length+sum2+i);
            sheet.addMergedRegion(cra);
        }
        //给未合并列的第二部分列写入标题
        for(int i=0; i<headers_3.length; i++){
            final Cell cell = row.createCell(headers_1.length+sum2+i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_3[i]);
        }
        //重新创建一行,写入合并列中的小列
        row = sheet.createRow(1);
        for(int i=0; i<headers_4.length; i++){
            final Cell cell = row.createCell(headers_1.length+i);
            cell.setCellStyle(style);
            cell.setCellValue(headers_4[i]);
        }

        // 遍历集合数据,产生数据行
        Iterator<Map<String,Object>> it = dataset.iterator();
        int index = 1;
        Map<String,Object> t;
        XSSFRichTextString richString;
        Pattern p = Pattern.compile("^//d+(//.//d+)?$");
        Matcher matcher;
        XSSFCell cell;
        Object value;
        String textValue;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            t = (Map<String,Object>) it.next();
            for (int i = 0; i < keys.size(); i++) {
                cell = row.createCell(i);
                cell.setCellStyle(style2);
                try {
                    value = t.get(keys.get(i));
                    // 判断值的类型后进行强制类型转换
                    textValue = null;
                    if (value instanceof Integer) {
                        cell.setCellValue((Integer) value);
                    } else if (value instanceof Float) {
                        textValue = String.valueOf((Float) value);
                        cell.setCellValue(textValue);
                    } else if (value instanceof Double) {
                        textValue = String.valueOf((Double) value);
                        cell.setCellValue(textValue);
                    } else if (value instanceof Long) {
                        cell.setCellValue((Long) value);
                    }
                    if (value instanceof Boolean) {
                        textValue = "是";
                        if (!(Boolean) value) {
                            textValue = "否";
                        }
                    } else if (value instanceof Date) {
                        textValue = sdf.format((Date) value);
                    } else {
                        // 其它数据类型都当作字符串简单处理
                        if (value != null) {
                            textValue = value.toString();
                        }
                    }
                    if (textValue != null) {
                        matcher = p.matcher(textValue);
                        if (matcher.matches()) {
                            // 是数字当作double处理
                            cell.setCellValue(Double.parseDouble(textValue));
                        } else {
                            richString = new XSSFRichTextString(textValue);
                            cell.setCellValue(richString);
                        }
                    }
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } finally {
                    // 清理资源
                }
            }
        }
        try {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

调用入口

    @RequestMapping("/exportExcel/{fileName}")
    public void exportExcle(@PathVariable("fileName") String fileName, HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        try {
            response.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8") + ".xls");//03版后缀为.xls 07版后缀为.xlsx
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        List<Map<String,Object>> list = new ArrayList<>();
        for(int i=0;i<10;i++){
            Map<String,Object> map = new HashMap<>();
            map.put("one","第"+(i+1)+"行的值");
            map.put("two","第"+(i+1)+"行的值");
            map.put("three","第"+(i+1)+"行的值");
            map.put("four","第"+(i+1)+"行的值");
            map.put("five","第"+(i+1)+"行的值");
            map.put("six","第"+(i+1)+"行的值");
            map.put("seven","第"+(i+1)+"行的值");
            map.put("eight","第"+(i+1)+"行的值");
            map.put("nine","第"+(i+1)+"行的值");
            map.put("ten","第"+(i+1)+"行的值");
            list.add(map);
        }
        List<String> keys2 = Arrays.asList("one","two","three","four","five","six","seven","eight","nine","ten");
        String[] headers_1 = {"部门","姓名"};
        String[] headers_2 = {"受理量","办结量"};
        String[] headers_3 = {"退件","补件"};
        String[] headers_4 = {"承诺件","即办件","总量","承诺件","即办件","总量"};
        int[] num = {3,3};//合并单元格各占列数
        try {
            ExportExcelUtil.exportExcel2003(fileName,headers_1,headers_2,headers_3,headers_4,num,list,keys2,response.getOutputStream(),"yyyy-MM-dd hh:mm:ss");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 截图

技术图片

 

java通过poi导出excel

标签:urlencode   依赖   图片   alt   jar   variable   get   exp   集中   

原文地址:https://www.cnblogs.com/lansetuerqi/p/14444491.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!