# POI :::info 1. [官方網站](https://poi.apache.org/index.html) 2. [官方文檔](https://poi.apache.org/apidocs/5.0/) 3. [官方教學](https://poi.apache.org/components/spreadsheet/quick-guide.html) 4. [Maven dependency](https://mvnrepository.com/artifact/org.apache.poi/poi) 最新版:5.3.0 ::: --- ## Workbook ```java= Workbook workbook = new HSSFWorkbook(); ``` - 用途: 代表一個 Excel 工作簿。 - 說明: 用於創建和管理 Excel 文件的頂層容器。HSSFWorkbook 是用於處理 .xls 格式的工作簿。 1. HSSF: .xls, for Excel 97-2003 2. XSSF: .xlsx, for Excel 2007 --- ## Sheet ```java= Sheet sheet = workbook.createSheet("05 Unidentified Payment"); ``` 用途: 代表工作簿中的一個工作表。 --- ## Row(橫的) ```java= Row row = sheet.createRow(rowIndex); Row row1 = sheet.createRow(0); ``` - 代表工作表中的一列。 - 要注意的是 Excel 的 Row 是從 0 開始算。 --- ## Cell(直的) ```java= Cell cellB9 = row8.createCell(1); // B9 儲存格 cellB9.setCellValue(42.5); // 設定數值 ``` - 代表一格儲存格,包含資料或公式。 - Excel 的 Cell 是從 0 開始算。 --- ## CellStyle ```java= CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); ``` 用於格式化儲存格的外觀(如對齊方式、數字格式)。 --- ## Font ```java= Font font = workbook.createFont(); font.setFontName("Times New Roman"); font.setBold(true); ``` 控制文字的字型、大小、粗體、斜體等格式。 --- ## FormulaEvaluator ```java= FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); evaluator.evaluateFormulaCell(cell); ``` 儲存格中的公式。 --- ## RichTextString ```java= RichTextString richText = workbook.getCreationHelper().createRichTextString(text); richText.applyFont(start, end, partialUnderlineFont); ``` 支援部分文字格式(如部分字串加底線)。 ![image](https://hackmd.io/_uploads/ByIJwJpeye.png) --- ## Merged Cells ```java= sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 4)); // 合併 C1:E1 ``` 合併多個儲存格成為一個儲存格。 ![image](https://hackmd.io/_uploads/S1IIwJTl1e.png) --- ## PropertyTemplate ```java= PropertyTemplate pt = new PropertyTemplate(); pt.drawBorders(new CellRangeAddress(26, 26, 0, 7), BorderStyle.THIN, BorderExtent.TOP); // 上框線 pt.applyBorders(sheet); ``` ![image](https://hackmd.io/_uploads/B1_9Dypeyl.png) --- # iText :::info 1. [官方文檔](https://api.itextpdf.com/iText/dotnet/latest/index.html) 2. [官方教學](https://kb.itextpdf.com/itext/itext-jump-start-tutorial-for-java) 3. [Maven dependency](https://mvnrepository.com/artifact/com.itextpdf/itext-core) 最新版:8.0.5 ::: --- ## Hello World ```java= PdfWriter writer = new PdfWriter(dest);//負責將 PDF 輸出到指定位置。 PdfDocument pdf = new PdfDocument(writer);//表示 PDF 文件的結構。 Document document = new Document(pdf);//處理 PDF 文件中的內容。 document.add(new Paragraph("Hello World!")); document.close(); ``` <!-- 1. PdfWriter is an object that can write a PDF file.The PdfWriter doesn't know what the document is about, it just writes different file parts and different objects that make up a valid document once the file structure is completed. 2. The PdfWriter knows what to write because it listens to a PdfDocument. The PdfDocument manages the content that is added, distributes that content over different pages, and keeps track of whatever information is relevant for that content. 3. Document that takes the PdfDocument as parameter. 4. Paragraph containing the text "Hello World" and we add that paragraph to the document object. --> --- ## Table ```java= Table table = new Table(UnitValue.createPercentArray(columnWidths)); ``` 用途: 用來創建 PDF 表格。 --- ## Paragraph / Text / Cell(PDF 用) ```java= Paragraph paragraph = new Paragraph(); Text text = new Text(content); com.itextpdf.layout.element.Cell pdfCell ``` - Paragraph:表示 PDF 文字段落。 - Text:用來顯示文字內容。 - Cell(PDF 用): 表示 PDF 表格中的儲存格。 <!-- --- ### PDF 的 Paragraph、Text 和 Cell 的差異 - 在 iText 中,Paragraph 和 Text 通常用於設置文字內容和段落樣式,而 Cell 是用來構建 表格中的儲存格,並且可以進一步包裹 Paragraph 或 Text。 - Cell 本身也可以進行格式化,但它的重點在於控制表格中的元素排列。 --> --- ## Color / Border ```java= pdfCell.setBorder(new SolidBorder(1)); text.setFontColor(ColorConstants.BLACK); ``` - Color : 顏色 - Border : 邊界 --- ## Excel2Pdf的核心邏輯: 1. 取得 Excel 的儲存格 (Cell) ```java= Cell excelCell = row.getCell(colIndex); ``` 2. 將 Excel Cell 內容轉換為 Paragraph ```java= Paragraph paragraph = createParagraphFromCell(excelCell, dataFormatter); ``` 3. 將 Paragraph 包入 PDF 的 Cell ```java= com.itextpdf.layout.element.Cell pdfCell = createMergedCell( mergedRegions, row.getRowNum(), colIndex, paragraph); ``` 4. 設定 PDF Cell 的樣式並加入表格 ```java= setCellStyle(excelCell, pdfCell); // 設定邊框、對齊方式 table.addCell(pdfCell); // 將儲存格加入 PDF 表格 ``` --- ## 部分底線的 cell 是怎麼實現的? 1. 將內容分成兩段 Text(部分底線,部分正常)。 ```java= Text text1 = new Text("Payment ") // 正常文字 Text text2 = new Text("Channel").setUnderline(); // 底線 Paragraph paragraph = new Paragraph().add(text1).add(text2); // 建立段落 ``` 2. 將段落放入 PDF 儲存格: ```java= com.itextpdf.layout.element.Cell pdfCell = new Cell().add(paragraph); pdfCell.setTextAlignment(TextAlignment.CENTER); // 設定置中 ``` --- ## 部分底線的 cell 是怎麼實現的? 3. 加入表格: ```java= table.addCell(pdfCell); // 將儲存格加入 PDF 表格 ``` ![image](https://hackmd.io/_uploads/S1IpfkCeyg.png) --- ## 限制 1. 算分頁問題 & 重複 header 問題: 無法準確計算分頁,不僅 Page 算不準,還會讓表格在奇怪的地方被截斷。 2. 數格子問題:因為使用字形不是等距字形所以沒辦法精確估算(?不確定是不是這個意思) 3. 格式一致性問題 : 主要是Excel 與 PDF 的格式差異,就算兩邊設定的欄寬一樣,會因為兩者使用的計算單位不同,難以完全一致。( Excel 的欄寬單位是 1/256 個字元,而 PDF 使用的是像素或百分比) --- ## 限制 5. 預先處理手動處理 EXCEL 欄位 : ITETX 無法模擬 EXCEL 在不改變欄寬的情況下,讓內容自由超出欄寬。內容有比較長的儲存格需要預先合併。 6. 如果我們是商用,可能會有字體版權問題(因為 Times New Roman 和 Calibri 都有版權) --- ### 格式問題 在固定欄寬的情況下僅調整字形(means of Payment)會造成欄高改變 ![image](https://hackmd.io/_uploads/SkcsEMAeyg.png) ![image](https://hackmd.io/_uploads/r1W-BfRl1l.png) 解決方式: 預留比較寬的欄位讓使用者填寫或是限制使用者輸入字數
{"description":"type: slide","title":"iText/POI 教學文檔","contributors":"[{\"id\":\"8dc6884a-7591-4462-8d43-07712a3f778b\",\"add\":7085,\"del\":1547}]","slideOptions":"{\"theme\":\"solarized\",\"transition\":\"slide\",\"center\":false}"}
    72 views