首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

iText 導出 PDF 實戰:中文字體支援、註解驅動、實體類自動映射

     編輯:Java 綜合教學

iText 導出 PDF 實戰:中文字體支援、註解驅動、實體類自動映射

核心依賴

  • itextpdf-5.5.x.jar (核心庫)
  • itext-asian-5.5.x.jar (亞洲字體支援,**解決中文亂碼關鍵**)

Jar 包依賴

註解定義:標記導出欄位

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PDFColumn {
    String header();      // 表頭名稱
    int order() default 0; // 列順序
    String format() default ""; // 格式化模板 (如日期)
}

註解定義 註解屬性

實體類範例

public class Employee {
    @PDFColumn(header = "員工編號", order = 1)
    private String empNo;
    
    @PDFColumn(header = "姓名", order = 2)
    private String name;
    
    @PDFColumn(header = "入職日期", order = 3, format = "yyyy-MM-dd")
    private Date hireDate;
    
    @PDFColumn(header = "薪資", order = 4, format = "#,##0.00")
    private BigDecimal salary;
    // getter/setter 省略
}

實體類使用註解

核心導出邏輯

public class PDFExporter {
    private static final Font CHINESE_FONT = new Font(
        BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 12);

    public static <T> void export(List<T> data, String filePath) throws Exception {
        Document doc = new Document(PageSize.A4.rotate()); // 橫向
        PdfWriter.getInstance(doc, new FileOutputStream(filePath));
        doc.open();
        
        // 1. 反射獲取註解欄位,按 order 排序
        List fields = Arrays.stream(data.get(0).getClass().getDeclaredFields())
            .filter(f -> f.isAnnotationPresent(PDFColumn.class))
            .sorted(Comparator.comparingInt(f -> f.getAnnotation(PDFColumn.class).order()))
            .collect(Collectors.toList());
        
        // 2. 建立表格
        PdfPTable table = new PdfPTable(fields.size());
        table.setWidthPercentage(100);
        
        // 3. 寫入表頭
        for (Field f : fields) {
            PDFColumn ann = f.getAnnotation(PDFColumn.class);
            PdfPCell cell = new PdfPCell(new Phrase(ann.header(), CHINESE_FONT));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell);
        }
        
        // 4. 寫入數據行
        for (T obj : data) {
            for (Field f : fields) {
                f.setAccessible(true);
                Object val = f.get(obj);
                String text = formatValue(val, f.getAnnotation(PDFColumn.class).format());
                PdfPCell cell = new PdfPCell(new Phrase(text, CHINESE_FONT));
                table.addCell(cell);
            }
        }
        
        doc.add(table);
        doc.close();
    }

    private static String formatValue(Object val, String pattern) {
        if (val == null) return "";
        if (val instanceof Date && !pattern.isEmpty()) 
            return new SimpleDateFormat(pattern).format(val);
        if (val instanceof Number && !pattern.isEmpty())
            return new DecimalFormat(pattern).format(val);
        return val.toString();
    }
}

導出邏輯1 導出邏輯2 導出邏輯3 導出邏輯4 導出邏輯5

測試驗證

@Test
public void testExport() throws Exception {
    List<Employee> list = Arrays.asList(
        new Employee("E001", "張三", new Date(), new BigDecimal("8500.50")),
        new Employee("E002", "李四", new Date(), new BigDecimal("12000.00"))
    );
    PDFExporter.export(list, "D:/employee.pdf");
}

測試類 測試方法

關鍵點總結

  • 中文不亂碼:必須引入 itext-asian 並使用 STSong-Light / UniGB-UCS2-H 字體編碼
  • 註解驅動:新增欄位只需在實體類加註解,零代碼修改導出邏輯
  • 格式化支援:日期、數字、貨幣等靈活模板
  • 橫向紙張:PageSize.A4.rotate() 適應寬表格
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved