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

    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM