Java使用POI的SXSSFWorkbook与HSSFWorkbook导出复杂表头

一、HSSFWorkbook与SXSSFWorkbook的区别:

HSSFWorkbook是对Excel2003以前的版本进行操作的,即后缀名为.xls

SXSSFWorkbook时对Excel2007的版本就行操作,即后缀名为.xlsx  

ps:

1、SXSSFWorkbook是在POI3.8版本开始提供基于XSSF低内存占用的SXSSF

SXSSF通过一个滑动窗口来限制访问Row的数量从而达到低内存占用的目录,XSSF可以访问所有行。SXSSF通过设置rowAccessWindowSize的大小实现滑动窗口中存储数据量的row数量,当行数超过滑动窗口设定的值时,此时旧的数据不再出现在滑动窗口且不可对此进行

访问,同时将此数据写入磁盘。也可通过flushRow(int keepRows)设定行数通过周期性的调用来修改。

注意:针对 SXSSF Beta 3.8下,会有临时文件产生,比如: 

poi-sxssf-sheet4654655121378979321.xml 

文件位置:java.io.tmpdir这个环境变量下的位置 

Windows 7下是C:\Users\xxxxxAppData\Local\Temp 

Linux下是 /var/tmp/ 

2、当数据量超出65536条后,在使用HSSFWorkbook或XSSFWorkbook,程序会报OutOfMemoryError:Javaheap space;内存溢出错误。这时应该用SXSSFworkbook

二、所需jar包

1、SXSSFWorkbook所需jar包

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.1</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>2.6.0</version>
</dependency>

2、HSSFWorkbook所需jar

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

三、代码实例:

1、SXSSFWorkbook:

package com.test.excel;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class SXSSFExecelPOI {

    public static void main(String[] args) {
        try {
            boolean createExcelFile = createExcelFile();
            if (createExcelFile) {
                System.out.println("SXSSF_excel导出成功");
            } else {
                System.out.println("SXSSFexcel导出失败");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static boolean createExcelFile() throws Exception {

        boolean state = false;
        OutputStream os = null;
        FileOutputStream fos = null;
        String resultFileName = null;
        String fileName = "";
        try {
            org.apache.poi.ss.usermodel.Workbook wb;
            fileName = "kemu.xlsx";
            wb = createReportWorkbook();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            resultFileName = "E:\\" + File.separator + "excel" + File.separator + sdf.format(new Date())
                    + File.separator + fileName;
            resultFileName = resultFileName.replaceAll("\\\\", "/");
            File file = new File(resultFileName);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
            }
            fos = new FileOutputStream(file);
            os = new BufferedOutputStream(fos, 1024);
            wb.write(os);
            os.flush();
            state = true;
        } finally {
            if (os != null)
                os.close();
        }
        return state;
    }

    private static Workbook createReportWorkbook() {
        String[] titles = { "时间", "科目", "科目", "科目", "科目", "备注" };
        String[] handClum = { "0,1,0,0", "0,0,1,4", "0,1,5,5" };

        String[] titles2 = { "时间", "科目一", "科目二", "科目三", "科目四", "备注" };

        // 100 指定Excel在屏幕尺寸下可滑动数据为100条
        SXSSFWorkbook wb = new SXSSFWorkbook(100);
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);// 设置单元格水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);// 设置单元格垂直居中
        Sheet sheet = wb.createSheet("sheet1");
        for (int i = 0; i < titles.length; i++) {
            sheet.setColumnWidth(i, 5000);
        }

        Row row = sheet.createRow(0);// 创建表头1
        for (int i = 0; i < titles.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(titles[i]);
        }

        // 动态合并单元格
        for (int i = 0; i < handClum.length; i++) {

            // sheet.autoSizeColumn(i, true);
            String[] temp = handClum[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow, startcol, overcol));
        }

        row = sheet.createRow(1);// 创建表头2

        for (int i = 0; i < titles2.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(titles2[i]);
        }

        List<keMu> kemus = new ArrayList<keMu>();
        for (int i = 0; i < 1000; i++) {
            keMu kemu = new keMu();
            kemu.setCreateDate("2018/11/06");
            kemu.setKe1("理论" + i);
            kemu.setKe2("模拟" + i);
            kemu.setKe3("上机" + i);
            kemu.setKe4("实操" + i);
            kemu.setRemark("通过");
            kemus.add(kemu);
        }
        // 填充数据
        if (kemus != null && kemus.size() > 0) {
            for (int i = 0; i < kemus.size(); i++) {
                Row contentRow = sheet.createRow(i + 2);// 填充类容,从第2行开始,0行给表头
                if (i % 100 == 0) {
                    try {
                        ((SXSSFSheet) sheet).flushRows(100);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                for (int j = 0; j < titles2.length; j++) {
                    Cell cell = contentRow.createCell(j);
                    cell.setCellStyle(style);
                    keMu content = kemus.get(i);
                    switch (j) {
                    case 0:
                        cell.setCellValue(content.getCreateDate());
                        break;
                    case 1:
                        cell.setCellValue(content.getKe1());
                        break;
                    case 2:
                        cell.setCellValue(content.getKe2());
                        break;
                    case 3:
                        cell.setCellValue(content.getKe3());
                        break;
                    case 4:
                        cell.setCellValue(content.getKe4());
                        break;
                    case 5:
                        cell.setCellValue(content.getRemark());
                        break;
                    }
                }
            }
        }

        return wb;
    }

    static class keMu {
        private String createDate;
        private String ke1;
        private String ke2;
        private String ke3;
        private String ke4;
        private String remark;

        public String getCreateDate() {
            return createDate;
        }

        public void setCreateDate(String createDate) {
            this.createDate = createDate;
        }

        public String getKe1() {
            return ke1;
        }

        public void setKe1(String ke1) {
            this.ke1 = ke1;
        }

        public String getKe2() {
            return ke2;
        }

        public void setKe2(String ke2) {
            this.ke2 = ke2;
        }

        public String getKe3() {
            return ke3;
        }

        public void setKe3(String ke3) {
            this.ke3 = ke3;
        }

        public String getKe4() {
            return ke4;
        }

        public void setKe4(String ke4) {
            this.ke4 = ke4;
        }

        public String getRemark() {
            return remark;
        }

        public void setRemark(String remark) {
            this.remark = remark;
        }

    }
}

2、HSSFWorkbook:

package com.test.excel;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
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.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

public class HSSFExcel {

    public static void main(String[] args) {
        try {
            boolean createExcelFile = createExcelFile();
            if (createExcelFile) {
                System.out.println("HSSF_excel导出成功");
            } else {
                System.out.println("hssf_excel导出失败");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static boolean createExcelFile() throws Exception {

        boolean state = false;
        OutputStream os = null;
        FileOutputStream fos = null;
        String resultFileName = null;
        String fileName = "";
        try {
            org.apache.poi.ss.usermodel.Workbook wb;
            fileName = "hkemu.xls";
            wb = createReportWorkbook();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            resultFileName = "E:\\" + File.separator + "excel" + File.separator + sdf.format(new Date())
                    + File.separator + fileName;
            resultFileName = resultFileName.replaceAll("\\\\", "/");
            File file = new File(resultFileName);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
            }
            fos = new FileOutputStream(file);
            os = new BufferedOutputStream(fos, 1024);
            wb.write(os);
            os.flush();
            state = true;
        } finally {
            if (os != null)
                os.close();
        }
        return state;
    }

    private static Workbook createReportWorkbook() {
        String[] titles = { "时间", "科目", "科目", "科目", "科目", "备注" };
        String[] handClum = { "0,1,0,0", "0,0,1,4", "0,1,5,5" };

        String[] titles2 = { "时间", "科目一", "科目二", "科目三", "科目四", "备注" };

        // 创建HSSFWorkbook对象,对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        // 在wb中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet("test");

        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);// 设置单元格水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);// 设置单元格垂直居中

        for (int i = 0; i < titles.length; i++) {
            sheet.setColumnWidth(i, 5000);
        }

        // 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        HSSFRow row = sheet.createRow(0);// 创建表头1
        for (int i = 0; i < titles.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(titles[i]);
        }

        // 动态合并单元格
        for (int i = 0; i < handClum.length; i++) {

            // sheet.autoSizeColumn(i, true);
            String[] temp = handClum[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow, startcol, overcol));
        }

        row = sheet.createRow(1);// 创建表头2
        for (int i = 0; i < titles2.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(titles2[i]);
        }

        List<keMu> kemus = new ArrayList<keMu>();
        for (int i = 0; i < 1000; i++) {
            keMu kemu = new keMu();
            kemu.setCreateDate("2018/11/06");
            kemu.setKe1("理论" + i);
            kemu.setKe2("模拟" + i);
            kemu.setKe3("上机" + i);
            kemu.setKe4("实操" + i);
            kemu.setRemark("通过");
            kemus.add(kemu);
        }
        // 填充数据
        if (kemus != null && kemus.size() > 0) {
            for (int i = 0; i < kemus.size(); i++) {
                HSSFRow contentRow = sheet.createRow(i + 2);// 填充类容,从第2行开始,0行给表头
                for (int j = 0; j < titles2.length; j++) {
                    HSSFCell cell = contentRow.createCell(j);
                    cell.setCellStyle(style);
                    keMu content = kemus.get(i);
                    switch (j) {
                    case 0:
                        cell.setCellValue(content.getCreateDate());
                        break;
                    case 1:
                        cell.setCellValue(content.getKe1());
                        break;
                    case 2:
                        cell.setCellValue(content.getKe2());
                        break;
                    case 3:
                        cell.setCellValue(content.getKe3());
                        break;
                    case 4:
                        cell.setCellValue(content.getKe4());
                        break;
                    case 5:
                        cell.setCellValue(content.getRemark());
                        break;
                    }
                }
            }
        }

        return wb;
    }

    static class keMu {
        private String createDate;
        private String ke1;
        private String ke2;
        private String ke3;
        private String ke4;
        private String remark;

        public String getCreateDate() {
            return createDate;
        }

        public void setCreateDate(String createDate) {
            this.createDate = createDate;
        }

        public String getKe1() {
            return ke1;
        }

        public void setKe1(String ke1) {
            this.ke1 = ke1;
        }

        public String getKe2() {
            return ke2;
        }

        public void setKe2(String ke2) {
            this.ke2 = ke2;
        }

        public String getKe3() {
            return ke3;
        }

        public void setKe3(String ke3) {
            this.ke3 = ke3;
        }

        public String getKe4() {
            return ke4;
        }

        public void setKe4(String ke4) {
            this.ke4 = ke4;
        }

        public String getRemark() {
            return remark;
        }

        public void setRemark(String remark) {
            this.remark = remark;
        }

    }
}

 

posted @ 2018-11-06 10:59  Mr.栋  阅读(8397)  评论(2编辑  收藏  举报