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

官方poi地址:

Busy Developers' Guide to HSSF and XSSF Features

HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的区别:

◎HSSFWorkbook一般用于Excel2003版及更早版本(扩展名为.xls)的导出。

◎XSSFWorkbook一般用于Excel2007版(扩展名为.xlsx)的导出。

◎SXSSFWorkbook一般用于大数据量的导出。

    /**
     * 导出人事档案目录  组织数据
     * @param list
     * @param personnelIdToList
     * @param qtyMap
     */
    @Override
    public void exportCatalogue(String year,
                                List<TnPersonnel> list,
                                Map<String, List<TrPersonnelCatalogue>> personnelIdToList,
                                Map<String, Integer> qtyMap) {
        Map<String, String> headMap = new LinkedHashMap<String, String>();// 存放表头部信息
        headMap.put("index", "序号");
        headMap.put("name", "材料名称");
        headMap.put("year", "年");
        headMap.put("month", "月");
        headMap.put("day", "日");
        headMap.put("total", "页数");
        headMap.put("remarks", "备注");
        String zipBucketName = CommonConstants.BUCKET_NAME + year + "excel";
        sysFileService.createBucket(zipBucketName);
        String fileName = year + "excel/";
        File f = new File(CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName);   //new的一个File对象
        //先删除之前的文件夹
        FileUtils.deleteQuietly(f);
        sysFileService.craertTreeFile(zipBucketName, fileName);
        for (TnPersonnel tnPersonnel : list) {
            String serialNumber = tnPersonnel.getSerialNumber();
            String name = tnPersonnel.getName();
            String id = tnPersonnel.getId();
            String title =  serialNumber + name + ".xlsx";
            String path = CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName + title;

            try {
                JSONObject personnelJo = new JSONObject();
                JSONArray catalogueJa = new JSONArray();
                List<TrPersonnelCatalogue> trPersonnelCatalogues = personnelIdToList.get(id);
                //添加大分类-
                List<TrPersonnelCatalogue> newCata = this.creatTitle(trPersonnelCatalogues);
                for (int i = 0; i < newCata.size(); i++) {
                    JSONObject jo = new JSONObject();
                    TrPersonnelCatalogue personnelCatalogue = newCata.get(i);
                    String catalogueId = personnelCatalogue.getId();
                    String cataDate = personnelCatalogue.getCataDate();
                    String createYear = "";
                    String month = "";
                    String day = "";
                    if(StringUtils.isNotBlank(cataDate)){
                        Date date = DateUtils.parseDate(cataDate, "yyyy-MM-dd");
                        createYear = DateUtils.formatDate(date, "yyyy");
                        month = DateUtils.formatDate(date, "MM");
                        day = DateUtils.formatDate(date, "dd");
                    }
                    String dateType = personnelCatalogue.getDateType();
                    String no = personnelCatalogue.getNo();
                    jo.put("index", no);
                    jo.put("name", personnelCatalogue.getName());
                    jo.put("year", createYear);
                    if("0".equals(dateType) || "2".equals(dateType) ||StringUtils.isBlank(dateType)){
                        jo.put("month", month);
                    }
                    if("2".equals(dateType) || StringUtils.isBlank(dateType)){
                        jo.put("day", day);
                    }
                    jo.put("total", qtyMap.get(catalogueId));
                    jo.put("remarks", "");
                    catalogueJa.add(jo);
                }
                personnelJo.put("name", name);
                personnelJo.put("catalogueJa", catalogueJa);

                // 生成文件临时存放目录
                File destination = new File(path);
                File dir = destination.getParentFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                if (!destination.exists()) {
                    destination.createNewFile();
                }
                OutputStream outXlsx = new FileOutputStream(destination);
                ExcleUtils.exportCatalogue(headMap, personnelJo, "yyyy-MM-dd", 6, outXlsx);
                outXlsx.close();
            } catch (Exception e) {
                System.out.println("导出异常");
                e.printStackTrace();
            }
        }
    }
/**
     * 导出人事档案目录  构建表头和页尾
     *
     * @param headMap  表头Map
     * @param personnelJo 表格内容
     * @param datePattern 日期格式
     * @param colWidth  列宽
     * @param out
     */
    public static void exportCatalogue(Map<String, String> headMap, JSONObject personnelJo,
                                       String datePattern, int colWidth, OutputStream out) {
        if (datePattern == null) datePattern = DEFAULT_DATE_PATTERN;
        // 声明一个工作薄
        SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
        workbook.setCompressTempFiles(true);
        //加外框样式
        CellStyle borderstyle = workbook.createCellStyle();
        borderstyle.setBorderBottom(BorderStyle.THIN); //下边框
        borderstyle.setBorderLeft(BorderStyle.THIN);//左边框
        borderstyle.setBorderTop(BorderStyle.THIN);//上边框
        borderstyle.setBorderRight(BorderStyle.THIN);//右边框
        borderstyle.setAlignment(HorizontalAlignment.CENTER);//文字居中
        borderstyle.setWrapText(true);
        //居中样式
        CellStyle centerCellStyle = workbook.createCellStyle();
        centerCellStyle.setAlignment(HorizontalAlignment.CENTER);
        //设置列宽
        int minBytes = colWidth < DEFAULT_COLOUMN_WIDTH ? DEFAULT_COLOUMN_WIDTH : colWidth;//至少字节数
        int[] arrColWidth = new int[headMap.size()];
        // 产生表格标题行,以及设置列宽
        String[] properties = new String[headMap.size()];
        String[] headers = new String[headMap.size()];
        int ii = 0;
        // 生成一个表格
        SXSSFSheet sheet = workbook.createSheet();
        //默认列宽
        sheet.setDefaultColumnWidth(5000);
        for (Iterator<String> iter = headMap.keySet().iterator(); iter
                .hasNext(); ) {
            String fieldName = iter.next();
            properties[ii] = fieldName;
            headers[ii] = headMap.get(fieldName);
            ii++;
        }
        sheet.setColumnWidth(1, 8000);
        // 页边距(左)
        sheet.setMargin(SXSSFSheet.LeftMargin,( double ) 1 );
        //设置打印页面为水平居中
        sheet.setHorizontallyCenter(true);
        //TODO 在POI的api中没有找到打印页面的得到方式
//        Footer footer = sheet.getFooter();
//        footer.setCenter( "第" + HeaderFooter.page() + "页,共 " + HeaderFooter.numPages()+"页" );
//        footer.setCenter(sheet.);
        //循环人员

        Object name = personnelJo.get("name");
        JSONArray catalogueJa = (JSONArray) JSONObject.toJSON(personnelJo.get("catalogueJa"));
        //第一行,表名
        SXSSFRow oneRow = sheet.createRow(0); //列头 rowIndex =1
        SXSSFCell cell = oneRow.createCell(0);
        cell.setCellValue("人事档案目录");
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) 15);
        font.setBold(true);
        cellStyle.setFont(font);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cell.setCellStyle(cellStyle);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));
        //第二行,姓名
        SXSSFRow nameRow = sheet.createRow(1); //列头 rowIndex =1
        SXSSFCell nameCell = nameRow.createCell(0);
        nameCell.setCellValue("姓名:" + name);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headers.length - 1));
        //第三行,表头
        SXSSFRow headerOne = sheet.createRow(2); //列头 rowIndex =1
        SXSSFRow headerTwo = sheet.createRow(3); //列头 rowIndex =1
        for (int i = 0; i < headers.length; i++) {
            SXSSFCell cell1 = headerOne.createCell(i);
            cell1.setCellValue(headers[i]);
            SXSSFCell cell2 = headerTwo.createCell(i);
            cell2.setCellValue(headers[i]);
            cell1.setCellStyle(borderstyle);
            cell2.setCellStyle(borderstyle);
        }
        SXSSFCell dateCell = headerOne.createCell(2);
        dateCell.setCellValue("材料形成日期");
        dateCell.setCellStyle(borderstyle);
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 0, 0));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 1, 1));
        sheet.addMergedRegion(new CellRangeAddress(2, 2, 2, 4));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 5, 5));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 6, 6));
        //生成表格内容
        updateCell(catalogueJa, sheet, properties,
                datePattern, borderstyle, headers, workbook, name, centerCellStyle);
        try {
            workbook.write(out);
            workbook.close();
//            boolean flag =  workbook.dispose();//释放磁盘空间。处理在磁盘上支持这个工作簿的临时文件。调用该方法将使工作簿不可用。
//            System.out.println(flag);//如果所有临时文件都被成功删除,则为真。
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  /**
     * @param catalogueJa, sheet, properties, datePattern, borderstyle
     * @return void
     * @Description :导出人事档案目录-生成表格内容
     * @author caohong
     * @date 2021/11/3
     */
    private static void updateCell(JSONArray catalogueJa,
                                   SXSSFSheet sheet, String[] properties,
                                   String datePattern, CellStyle borderstyle,
                                   String[] headers, SXSSFWorkbook workbook,
                                   Object name,CellStyle centerCellStyle) {
        // 遍历集合数据,产生数据行
        int rowIndex = 4;
        //记录打印时每页行数
        int printRow = 0;
        //记录打印时每页总行数
        int totalRow = 40;
        //页码
        int page = 1;
        ArrayList<String> noArr = creatTitle();
        for (Object object : catalogueJa) {
            JSONObject catalogueJo = (JSONObject) JSONObject.toJSON(object);
            SXSSFRow dataRow = sheet.createRow(rowIndex);
            for (int i = 0; i < properties.length; i++) {
                Object o = catalogueJo.get(properties[i]);
                String cellValue = "";
                if (o == null) cellValue = "";
                else if (o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
                else if (o instanceof Float || o instanceof Double)
                    cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                else cellValue = o.toString();

                if (i == 0 && noArr.indexOf(cellValue) > -1) {
                    if (printRow < totalRow) {
                        int j = totalRow - printRow;
                        //处理空行
                        for (int k = 1; k < j; k++) {
                            SXSSFRow dataRowBlank = sheet.createRow(rowIndex++);
                            for (int a = 0; a < properties.length; a++) {
                                if (k == 1) {
                                    SXSSFCell newCell = dataRow.createCell(a);
                                    //设置边框
                                    newCell.setCellStyle(borderstyle);
                                }
                                SXSSFCell newCell = dataRowBlank.createCell(a);
                                //设置边框
                                newCell.setCellStyle(borderstyle);
                            }
                        }
                    }
                    //页尾
                    SXSSFRow endRow = sheet.createRow(rowIndex);
                    SXSSFCell pgaeCell = endRow.createCell(0);
                    pgaeCell.setCellValue("第" + page + "页");
                    pgaeCell.setCellStyle(centerCellStyle);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
                    rowIndex = rowIndex + 1;
                    //设置在特定行的添加分页符
                    sheet.setRowBreak(rowIndex - 1);
                    //添加分页符之后,重置打印行数
                    printRow = 0;
                    //第一行,表名
                    SXSSFRow oneRow = sheet.createRow(rowIndex); //列头 rowIndex =1
                    SXSSFCell cell = oneRow.createCell(0);
                    cell.setCellValue("人事档案目录");
                    CellStyle cellStyle = workbook.createCellStyle();
                    Font font = workbook.createFont();
                    font.setFontHeightInPoints((short) 15);
                    font.setBold(true);
                    cellStyle.setFont(font);
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cell.setCellStyle(cellStyle);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
                    //第二行,姓名
                    SXSSFRow nameRow = sheet.createRow(rowIndex + 1); //列头 rowIndex =1
                    SXSSFCell nameCell = nameRow.createCell(0);
                    nameCell.setCellValue("姓名:" + name);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 1, 0, headers.length - 1));
                    //第三行,表头
                    SXSSFRow headerOne = sheet.createRow(rowIndex + 2); //列头
                    SXSSFRow headerTwo = sheet.createRow(rowIndex + 3); //列头
                    for (int b = 0; b < headers.length; b++) {
                        SXSSFCell cell1 = headerOne.createCell(b);
                        cell1.setCellValue(headers[b]);
                        SXSSFCell cell2 = headerTwo.createCell(b);
                        cell2.setCellValue(headers[b]);
                        cell1.setCellStyle(borderstyle);
                        cell2.setCellStyle(borderstyle);
                    }
                    SXSSFCell dateCell = headerOne.createCell(2);
                    dateCell.setCellValue("材料形成日期");
                    dateCell.setCellStyle(borderstyle);
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 0, 0));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 1, 1));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 2, 2, 4));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 5, 5));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 6, 6));
                    //加表头行数
                    rowIndex = rowIndex + 4;
                    //生成
                    dataRow = sheet.createRow(rowIndex);
                    page++;
                }
                SXSSFCell newCell = dataRow.createCell(i);
                //填充内容
                newCell.setCellValue(cellValue);
                //设置边框
                newCell.setCellStyle(borderstyle);
            }
            rowIndex++;
            printRow++;
        }
        if (printRow < totalRow) {
            int j = totalRow - printRow;
            //处理空行
            for (int k = 1; k < j; k++) {
                SXSSFRow dataRowBlank = sheet.createRow(rowIndex);
                for (int a = 0; a < properties.length; a++) {
                    SXSSFCell newCell = dataRowBlank.createCell(a);
                    //设置边框
                    newCell.setCellStyle(borderstyle);
                }
                rowIndex++;
            }
        }
        //页尾
        SXSSFRow endRow = sheet.createRow(rowIndex);
        SXSSFCell pgaeCell = endRow.createCell(0);
        pgaeCell.setCellValue("第" + page + "页");
        pgaeCell.setCellStyle(centerCellStyle);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
        //取消excel默认的自动分页,打印时将excel文件打印在pdf的一页中。
        sheet.setAutobreaks(true);
    }
项目引用
<poi.version>3.17</poi.version>


        <!-- poi office -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-examples</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>${poi.version}</version>
        </dependency>

猜你喜欢

转载自blog.csdn.net/ole_triangle_java/article/details/121418804