最近項(xiàng)目中用到itext來將html轉(zhuǎn)換為pdf纤泵,itext功能確實(shí)強(qiáng)大能方便的讓您操作pdf文件骆姐。同樣其對中文也支持的挺好。
? 在默認(rèn)配置情況下捏题,中文是不能顯示的或者顯示為亂碼玻褪。為解決此問題,搜遍網(wǎng)絡(luò)公荧,得出結(jié)論是在創(chuàng)建paragrahp時(shí)將中文字體傳遞給pdfdocument带射。但問題是在項(xiàng)目中需要將html轉(zhuǎn)換為pdf文件,這樣創(chuàng)建paragrahp是由html解析器進(jìn)行處理的循狰,總不能修改itext源代碼吧窟社?miciu網(wǎng)站的大大就是用此方案,將itext中3個(gè)源代碼修改從而保證中文可以顯示绪钥。
? 不過miciu網(wǎng)站大大思路啟發(fā)了我去研究itext的源代碼灿里。使用itext來轉(zhuǎn)換html到pdf時(shí),在新版本中5.4.2中用xmlworker組件是比較明智的選擇程腹。通過研究發(fā)現(xiàn)itext xmlworker實(shí)際提供了某種擴(kuò)展方式來顯示中文匣吊,特別是中文默認(rèn)字體問題。對于沒有顯示聲明css樣式的字體跪楞,默認(rèn)使用undefine字體樣式缀去,這對于英文是可行的,對于中文來說甸祭,這是不可接受的缕碎,因此擴(kuò)展其字體提供方式,讓轉(zhuǎn)換器在轉(zhuǎn)換過程中碰到默認(rèn)字體用宋體來顯示池户,這樣就解決了中文不能顯示或者亂碼的問題咏雌。
? 具體代碼參考如下:
```
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.Pipeline;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.exceptions.C***esolverException;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.C×××esolver;
import com.itextpdf.tool.xml.pipeline.css.C***esolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
public class XMLWorkerDemo {
? ? public static class MyFontsProvider extends XMLWorkerFontProvider{
? ? ? ? public MyFontsProvider(){
? ? ? ? ? ? super(null,null);
? ? ? ? }
? ? ? ? @Override
? ? ? ? public Font getFont(final String fontname, String encoding, float size, final int style) {
? ? ? ? ? ? String fntname = fontname;
? ? ? ? ? ? if(fntname==null){
? ? ? ? ? ? ? ? fntname="宋體";
? ? ? ? ? ? }
? ? ? ? ? ? return super.getFont(fntname, encoding, size, style);
? ? ? ? }
? ? }
? ? private static String dirpath = "";
? ? public static void main(String[] args) throws FileNotFoundException, IOException, DocumentException, C***esolverException {
? ? ? ? convert2("d:/test0.html","d:/test.pdf");
? ? }
? ? public static void convert2(String infile, String outfile)
? ? ? ? ? ? throws FileNotFoundException, IOException, DocumentException,
? ? ? ? ? ? C***esolverException {
? ? ? ? Document document = new Document();
? ? ? ? PdfWriter writer = PdfWriter.getInstance(document,
? ? ? ? ? ? ? ? new FileOutputStream(outfile));
? ? ? ? document.open();
? ? ? ? XMLWorkerDemo.MyFontsProvider fontProvider = new XMLWorkerDemo.MyFontsProvider();
? ? ? ? fontProvider.addFontSubstitute("lowagie", "garamond");
? ? ? ? fontProvider.setUseUnicode(true);
? ? ? ? //使用我們的字體提供器,并將其設(shè)置為unicode字體樣式
? ? ? ? CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
? ? ? ? HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
? ? ? ? htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
? ? ? ? C×××esolver c***esolver = XMLWorkerHelper.getInstance()
? ? ? ? ? ? ? ? .getDefaultC***esolver(true);
? ? ? ? Pipeline<?> pipeline = new C***esolverPipeline(c***esolver,
? ? ? ? ? ? ? ? new HtmlPipeline(htmlContext, new PdfWriterPipeline(document,
? ? ? ? ? ? ? ? ? ? ? ? writer)));
? ? ? ? XMLWorker worker = new XMLWorker(pipeline, true);
? ? ? ? XMLParser p = new XMLParser(worker);
? ? ? ? File input = new File(infile);
? ? ? ? p.parse(new InputStreamReader(new FileInputStream(input), "UTF-8"));
? ? ? ? document.close();
? ? }
}
```
以上代碼能解決大部分中文網(wǎng)頁轉(zhuǎn)換為pdf文件的中文不顯示或亂碼問題校焦,需要注意的是xmlworker只支持xhtml文件即嚴(yán)格意義的html赊抖,若是普通html文件,很容易發(fā)生異常 no expect tag input等寨典,常見的不封閉的標(biāo)簽有:input氛雪、link、metadata耸成、script报亩、p_w_picpath浴鸿、br等,如何解決html到xhtml或直接使用itext的htmlpareser解決此問題將是后續(xù)研究的問題弦追,若有結(jié)論岳链,將分享給給位。
還有個(gè)問題需要解決的是對于某些字體itext還是不能很好的處理劲件,我們這邊碰到的是楷體掸哑,對于楷體轉(zhuǎn)換的pdf文件中還是不能顯示對應(yīng)的中文文字,后面若有解決方案再與諸位分享零远,若各位有相關(guān)的解決方案也請不吝賜教