• java通过poi导出excel


    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();
            }
        }

    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") + ".xlsx");//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> keys = Arrays.asList("one","two","three","four","five","six","seven","eight","nine","ten");
            String[] headers = {"第1列","第2列","第3列","第4列","第5列","第6列","第7列","第8列","第9列","第10列"};
            String[] headers_1 = {"部门","姓名"};
            String[] headers_2 = {"受理量","办结量"};
            String[] headers_3 = {"退件","补件"};
            String[] headers_4 = {"承诺件","即办件","总量","承诺件","即办件","总量"};
            int[] num = {3,3};//合并单元格各占列数
            try {
                //以下调用一次执行一个
                //03版单一标题
                //ExportExcelUtil.exportExcel2003(fileName, headers, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys);
                //07版无标题
                //ExportExcelUtil.exportExcel2007(fileName, null, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys);
                //03版单元格合并
                //ExportExcelUtil.exportExcel2003(fileName,headers_1,headers_2,headers_3,headers_4,num,list,keys,response.getOutputStream(),"yyyy-MM-dd hh:mm:ss");
                //07版单元格合并
                ExportExcelUtil.exportExcel2007(fileName,headers_1,headers_2,headers_3,headers_4,num,list,keys,response.getOutputStream(),"yyyy-MM-dd hh:mm:ss");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    无标题

    有标题

     单元格合并

     ~~ 学如逆水行舟 不进则退

  • 相关阅读:
    自定义View
    Android Parcelable
    java IO
    如何安全退出已调用多个Activity的Application?
    cookie和session
    Excel 使用AutoFill提示“类Range的AutoFill方法无效”
    解决“配置系统未能初始化”问题
    Android控件第7类——对话框
    Android控件第6类——杂项控件
    Android控件第5类——ViewAnimator
  • 原文地址:https://www.cnblogs.com/lansetuerqi/p/14444491.html
Copyright © 2020-2023  润新知