iText生成中文PDF行首標點處理 原 薦

我用的是iText-5.5.10,版本差別不是很大的話,應該都可以這麼修改

最近在使用iText生成PDF時,遇到了行首標點問題,可是找了半天,也沒找到一個明確的可行解決方案,後來找到一個看着比較靠譜的,http://bbs.csdn.net/topics/380075439,也說的模模糊糊的,試了也沒好使,不過也提供了一個思路。

下面直接上乾貨

  1. 下載iText源碼,改源碼是最直接有效的
  2. 解壓後將itext子項目導入開發工具中,待會改完後還要重新打包的
  3. 添加一箇中文標點數據類
    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('?');
            /**  添加你所需的標點  ***/
        }
    }

     

  4. 找到類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行(不同版本,可能會有點差別)

  5. 到這,內容中的行首中文標點只調整好了一半,下面圖1這種情況已經Ok了,但圖2還不行圖1圖2
  6. 接着來,找到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--;
    }

    (備註:這裏的修改我使用的是將上一行的最後一個字挪下來的方式)

  7. 到這,修改就完了,將項目重新打包,引入到你的項目中,再試下生成的PDF效果

補充:

    到了實際應用時,出現了一種空行的問題,如下圖

    

    所以再添加一點改進,解決這個問題

    找到com.itextpdf.text.pdf.PdfLine文件中的add(PdfChunk chunk)方法

    在“newlineSplit = chunk.isNewlineSplit() || overflow == null;”前添加如下代碼

if(overflow != null && overflow.value.trim().length() == 0){
	overflow = null;
}

再試下,看是不是搞定了呢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章