首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Apache POI 導出 Excel 實戰指南:通用導出工具類

     編輯:關於C++

Apache POI 簡介

Apache POI 是 Apache 基金會開源專案,提供 Java API 操作 Microsoft Office 格式檔案。核心元件:

  • HSSF:處理 Excel 97-2003 (.xls)
  • XSSF:處理 Excel 2007+ (.xlsx)
  • HWPF、HSLF、HDGF 等處理 Word、PowerPoint、Visio 等格式

官方快速指南:https://poi.apache.org/spreadsheet/quick-guide.html

通用導出工具類設計

利用 Java 反射機制,支援任意符合 JavaBean 風格的類別,自動將集合資料導出為 Excel。支援基本型別、String、Date、byte[](圖片)。

實體類別範例

public class Student {
    private long id;
    private String name;
    private int age;
    private boolean sex; // true=男, false=女
    private Date birthday;
    // getter/setter 略
}

public class Book {
    private int id;
    private String name, author, isbn, publisher;
    private float price;
    private byte[] coverImage; // JPEG 圖片資料
    // getter/setter 略
}

核心導出類 ExportExcel<T>

public class ExportExcel {
    // 多載方法,預設標題與日期格式
    public void exportExcel(Collection dataset, OutputStream out) {
        exportExcel("測試POI導出EXCEL文檔", null, dataset, out, "yyyy-MM-dd");
    }
    public void exportExcel(String[] headers, Collection dataset, OutputStream out) {
        exportExcel("測試POI導出EXCEL文檔", headers, dataset, out, "yyyy-MM-dd");
    }
    public void exportExcel(String[] headers, Collection dataset, OutputStream out, String pattern) {
        exportExcel("測試POI導出EXCEL文檔", headers, dataset, out, pattern);
    }

    /** 通用導出方法 */
    @SuppressWarnings("unchecked")
    public void exportExcel(String title, String[] headers, Collection dataset,
                            OutputStream out, String pattern) {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(title);
        sheet.setDefaultColumnWidth((short) 15);

        // 標題樣式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
        headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        HSSFFont headerFont = workbook.createFont();
        headerFont.setColor(HSSFColor.VIOLET.index);
        headerFont.setFontHeightInPoints((short) 12);
        headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        headerStyle.setFont(headerFont);

        // 資料樣式
        HSSFCellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
        dataStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        dataStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        dataStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        dataStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        dataStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        dataStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        dataStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        HSSFFont dataFont = workbook.createFont();
        dataFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        dataStyle.setFont(dataFont);

        // 繪圖管理器(用於插入圖片/註解)
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        HSSFComment comment = patriarch.createComment(
            new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
        comment.setString(new HSSFRichTextString("可以在POI中添加註解!"));
        comment.setAuthor("leno");

        // 寫入標題列
        HSSFRow headerRow = sheet.createRow(0);
        for (short i = 0; i < headers.length; ++i) {
            HSSFCell cell = headerRow.createCell(i);
            cell.setCellStyle(headerStyle);
            cell.setCellValue(new HSSFRichTextString(headers[i]));
        }

        // 遍歷資料集,利用反射寫入資料列
        Iterator it = dataset.iterator();
        int rowIdx = 0;
        while (it.hasNext()) {
            ++rowIdx;
            HSSFRow row = sheet.createRow(rowIdx);
            T obj = it.next();
            Field[] fields = obj.getClass().getDeclaredFields();
            for (short i = 0; i < fields.length; ++i) {
                HSSFCell cell = row.createCell(i);
                cell.setCellStyle(dataStyle);
                Field field = fields[i];
                String getter = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                try {
                    Method method = obj.getClass().getMethod(getter);
                    Object value = method.invoke(obj);
                    String textValue = null;

                    if (value instanceof Boolean) {
                        textValue = (Boolean)value ? "男" : "女";
                    } else if (value instanceof Date) {
                        textValue = new SimpleDateFormat(pattern).format((Date)value);
                    } else if (value instanceof byte[]) {
                        // 插入圖片
                        row.setHeightInPoints(60);
                        sheet.setColumnWidth(i, (short)(35.7 * 80));
                        byte[] bs = (byte[])value;
                        HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short)6,rowIdx,(short)6,rowIdx);
                        anchor.setAnchorType(2);
                        patriarch.createPicture(anchor, workbook.addPicture(bs, HSSFWorkbook.PICTURE_TYPE_JPEG));
                    } else {
                        textValue = value.toString();
                    }

                    if (textValue != null) {
                        // 純數字轉 double,其餘藍字顯示
                        if (textValue.matches("^\\d+(\\.\\d+)?$")) {
                            cell.setCellValue(Double.parseDouble(textValue));
                        } else {
                            HSSFRichTextString rich = new HSSFRichTextString(textValue);
                            HSSFFont f = workbook.createFont();
                            f.setColor(HSSFColor.BLUE.index);
                            rich.applyFont(f);
                            cell.setCellValue(rich);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

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

    // 測試 main 方法略
}

使用範例

ExportExcel ex = new ExportExcel<>();
String[] headers = {"學號","姓名","年齡","性別","出生日期"};
List data = Arrays.asList(
    new Student(10000001, "張三", 20, true, new Date()),
    new Student(20000002, "李四", 24, false, new Date())
);
ex.exportExcel(headers, data, new FileOutputStream("students.xls"));

關鍵特性

  • 泛型支援任意 JavaBean
  • 反射自動匹配屬性與表頭
  • 內建樣式、圖片、註解、數字格式化
  • 可直接輸出到檔案或網路串流
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved