我用的是iText-5.5.10,版本差別不是很大的話,應該都可以這麼修改
最近在使用iText生成PDF時,遇到了行首標點問題,可是找了半天,也沒找到一個明確的可行解決方案,後來找到一個看着比較靠譜的,http://bbs.csdn.net/topics/380075439,也說的模模糊糊的,試了也沒好使,不過也提供了一個思路。
下面直接上乾貨
- 下載iText源碼,改源碼是最直接有效的
- 解壓後將itext子項目導入開發工具中,待會改完後還要重新打包的
- 添加一箇中文標點數據類
package com.itextpdf.text.pdf; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2017/6/16. */ public class ChineseSymbolSplit { public static List<Character> chSymSplits; static { chSymSplits = new ArrayList<Character>(); chSymSplits.add(','); chSymSplits.add('、'); chSymSplits.add('。'); chSymSplits.add(':'); chSymSplits.add('!'); chSymSplits.add(';'); chSymSplits.add('?'); /** 添加你所需的標點 ***/ } }
- 找到類com.itextpdf.text.pdf.PdfChunk的split(float width)方法中修改
爲if (character == ' ') { lastSpace = currentPosition + 1; lastSpaceWidth = currentWidth; }
if (character == ' ' || ChineseSymbolSplit.chSymSplits.contains(character)) { lastSpace = currentPosition + 1; lastSpaceWidth = currentWidth; }
大概在367行和402行(不同版本,可能會有點差別)
- 到這,內容中的行首中文標點只調整好了一半,下面圖1這種情況已經Ok了,但圖2還不行圖1圖2
- 接着來,找到com.itextpdf.text.pdf.BidiLine中trimRightEx(int startIdx, int endIdx)方法,在"return idx;"前添加
//當下一個元素是標點時,前移一位 if(ChineseSymbolSplit.chSymSplits.contains(text[idx + 1]) && idx > 0){ idx--; }
找到trimLeftEx(int startIdx, int endIdx)方法前,在"return idx;"前添加
//當前元素是標點時,前移一位 if(ChineseSymbolSplit.chSymSplits.contains(text[idx]) && idx > 0){ idx--; }
(備註:這裏的修改我使用的是將上一行的最後一個字挪下來的方式)
- 到這,修改就完了,將項目重新打包,引入到你的項目中,再試下生成的PDF效果
補充:
到了實際應用時,出現了一種空行的問題,如下圖
所以再添加一點改進,解決這個問題
找到com.itextpdf.text.pdf.PdfLine文件中的add(PdfChunk chunk)方法
在“newlineSplit = chunk.isNewlineSplit() || overflow == null;”前添加如下代碼
if(overflow != null && overflow.value.trim().length() == 0){
overflow = null;
}
再試下,看是不是搞定了呢