IText 導出PDF 中文問題解決

使用的jar包用maven導入依賴
<!--PDF-->
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itextpdf</artifactId>
  <version>5.4.2</version>
</dependency>
<dependency>
  <groupId>com.itextpdf.tool</groupId>
  <artifactId>xmlworker</artifactId>
  <version>5.4.1</version>
</dependency>
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itext-asian</artifactId>
  <version>5.2.0</version>
</dependency>
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>flying-saucer-pdf</artifactId>
  <version>9.0.3</version>
</dependency>
<!--PDF-->
/**
     * 導出爲 PDF
     *
     * @param
     * @return
     * @throws BusinessException
     */
    public static String specialExportPDF(String moduleName, String fileName, Map<String, String> dataMap) throws BusinessException {
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");

        try {
            //dataMap 要填入模本的數據文件
            //設置模本裝置方法和路徑,FreeMarker支持多種模板裝載方法。可以重servlet,classpath,數據庫裝載,
            //這裏我們的模板是放在template包下面
            configuration.setDirectoryForTemplateLoading(new File(FileUtil.getWebRootPath() + "template//import//" + moduleName));
            Template t = null;
            try {
                //.ftl爲要裝載的模板
                t = configuration.getTemplate(fileName + ".ftl");
            } catch (IOException e) {
                e.printStackTrace();
            }
            fileName = fileName + DateUtil.datetimeToNoSplashString(DateUtil.now()) + ".html";
            String outputFilePath = getOutputXlsTempFilePath(fileName);
            Writer out = null;
            FileOutputStream fos = null;
            try {
                {
                    //輸出文檔路徑及名稱
                    fos = new FileOutputStream(outputFilePath);
                    OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
                    //這個地方對流的編碼不可或缺,使用main()單獨調用時,應該可以,但是如果是web請求導出時導出後word文檔就會打不開,並且包XML文件錯誤。主要是編碼格式不正確,無法解析。
                    //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
                    out = new BufferedWriter(oWriter);
                    t.process(dataMap, out);
                    String html = readString(outputFilePath);
                    //創建pdf
                    ItextUtil.createPdf(html,outputFilePath);
                    out.flush();
                    out.close();
                    fos.close();
                    //刪除html文件
                   File file = new File(outputFilePath);
                   file.delete();
                }
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (TemplateException e1) {
                e1.printStackTrace();
            }
            //4.返回word文件的下載地址
            return getDownloadXlsTempFileUrl(fileName.replace("html","pdf"));
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 讀取文件轉換爲字符串
     * @param FilePath
     * @return
     */
    private static String readString(String FilePath){
        if(PubUtil.isEmpty(FilePath))return "";
        int len=0;
        StringBuffer str=new StringBuffer("");
        File file=new File(FilePath);
        try {

            FileInputStream is=new FileInputStream(file);
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            String line=null;
            while( (line=in.readLine())!=null ){
                if(len != 0) {// 處理換行符的問題
                    str.append("\r\n"+line);
                }else{
                    str.append(line);
                }
                len++;
            }
            in.close();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str.toString();
    }
/** PDF生成工具 **/
package com.etom.ebihm.utils;


import com.itextpdf.text.*;
//import com.itextpdf.text.html.simpleparser.HTMLWorker;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.css.CssFile;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;


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.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.itextpdf.text.html.simpleparser.StyleSheet;
import com.itextpdf.text.pdf.PdfWriter;
//import com.lowagie.text.html.simpleparser.HTMLWorker;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.util.List;
//import java.util.ArrayList;

/**
 * 生成PDF工具類
 * Created by Administrator on 2017/8/21.
 */
public class ItextUtil {
//這裏的html是將html轉化爲字符串,非html文件路徑
    public static void createPdf(String html,String outPath) {
        ItextUtil ih = new ItextUtil();
        ih.htmlCodeComeFromFile(html,outPath.replace("html","pdf"));
    }
    public void htmlCodeComeFromFile(String html, String pdfPath) {
        Document document = new Document();
        try {
            /*StyleSheet st = new StyleSheet();
            st.loadTagStyle("body", "leading", "16,0");*/
            PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
            document.open();
            Paragraph context = new Paragraph( );
            ElementList elementList = parseToElementList(html, null);
            // 解決中文問題
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font FontChinese = new Font(bfChinese, 12, Font.NORMAL);
            context.setFont(FontChinese);
            for (com.itextpdf.text.Element element1 : elementList) {
                context.add(element1);
            }
            document.add(context);
            document.close();
            System.out.println("文檔創建成功");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public   ElementList parseToElementList(String html, String css) throws IOException {
        // CSS
        CSSResolver cssResolver = new StyleAttrCSSResolver();
        if (css != null) {
            CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
            cssResolver.addCss(cssFile);
        }
        // HTML
        MyXMLWorkerHelper.MyFontsProvider fontProvider = new MyXMLWorkerHelper.MyFontsProvider();
        CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
        HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
        htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
        htmlContext.autoBookmark(false);

        // Pipelines
        ElementList elements = new ElementList();
        ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
        HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
        CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);

        // XML Worker
        XMLWorker worker = new XMLWorker(cssPipeline, true);
        XMLParser p = new XMLParser(worker);
        p.parse(new ByteArrayInputStream(html.getBytes()));

        return elements;
    }
}



/**  重寫XMLWorkerHelper類,使用自定義字體    **/
package com.etom.ebihm.utils;

import com.etom.framework.constant.SystemConstants;
import com.etom.framework.utils.FileUtil;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;

import java.io.File;

/**
 * Created by Administrator on 2017/8/21.
 */
public class MyXMLWorkerHelper {
    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 = "宋體";
            }
            Font font = new Font();
            String font_cn = getChineseFont();
            BaseFont bf;
            try {
                bf = BaseFont.createFont(font_cn+",1", //注意這裏有一個,1
                        BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                font = new Font(bf,12);
                font.setFamily("SYMBOL");
            }catch (Exception e){
                e.printStackTrace();
            }
            //return super.getFont(fntname, encoding, size, style);
            return font;
        }
    }
    /**
     * 獲取中文字體位置
     * @return
     *  @author xxj 2017年4月28日
     */
    private static String getChineseFont(){
        //宋體(對應css中的 屬性 font-family: SimSun; /*宋體*/)
       /* String font1 ="C:/Windows/Fonts/simsun.ttc";


        //判斷系統類型,加載字體文件
        java.util.Properties prop = System.getProperties();
        String osName = prop.getProperty("os.name").toLowerCase();
        System.out.println(osName);*/
        //File  file = new File(FileUtil.getRealPath(SystemConstants.PATH_PRE_WEBROOT+"://res/font/simsun.ttc"));
        /*if (osName.indexOf("linux")>-1) {
            font1="/usr/share/fonts/simsun.ttc";
        }
        if(!new File(font1).exists()){
            throw new RuntimeException("字體文件不存在,影響導出pdf中文顯示!"+font1);
        }*/
	//linux服務器中未安裝字體,故在項目資源中傳了字體,獲取項目字體即可
        File  file = new File(FileUtil.getRealPath(SystemConstants.PATH_PRE_WEBROOT+"://res/font/simsun.ttc"));
        String font1 =FileUtil.getRealPath(SystemConstants.PATH_PRE_WEBROOT+"://res/font/simsun.ttc");
        if(!file.exists()){
            throw new RuntimeException("字體文件不存在,影響導出pdf中文顯示!"+font1);
        }
        return font1;
    }
}








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