PDF生成工具類(copy 代碼直接可用)

import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;


/**
 * <p>
 * Title: PdfUtils.java
 * </p>
 * <p>
 * Description: PDF生成工具類
 * </p>
 * <p>
 * Company:
 * </p>
 * 
 * @author huxuewei
 * @version v1.0
 */
@SuppressWarnings("all")
public class PDFUtil {

    

    /**
     * <p>
     * Description: 生成PDF到文件
     * </p>
     * <p>
     * Company:
     * </p>
     * 
     * @author ZY
     * @param ftlPath
     *            模板文件路徑(不含文件名)
     * @param ftlName
     *            模板文件(不含路徑)
     * @param imageDiskPath
     *            圖片的磁盤路徑
     * @param data
     *            數據 (填到模板上的數據)
     * @param outputFile
     *            目標文件(全路徑名稱)
     * @throws Exception
     */
    public static void generateToFile(String ftlPath, String ftlName, String imageDiskPath, Object data,
            String outputFile) throws Exception {
        OutputStream out = null;
        ITextRenderer render = null;
        try {
            String html = getPdfContent(ftlPath, ftlName, data); // 組裝模板和數據生成html串
            out = new FileOutputStream(outputFile);
            render = getRender();
            render.setDocumentFromString(html); // 此處拋異常
            if (imageDiskPath != null && !imageDiskPath.equals("")) {
                // html中如果有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這個是作爲根路徑
                render.getSharedContext().setBaseURL("file:/" + imageDiskPath);
            }
            render.layout();
            render.createPDF(out);
            render.finishPDF();
            render = null;
        } catch (Exception e) {
            
            throw e;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    
                    throw e;
                }
            }
        }
    }

    /**
     * 生成PDF到輸出流中(ServletOutputStream用於下載PDF)
     * 
     * @param ftlPath
     *            ftl模板文件的路徑(不含文件名)
     * @param ftlName
     *            ftl模板文件的名稱(不含路徑)
     * @param imageDiskPath
     *            如果PDF中要求圖片,那麼需要傳入圖片所在位置的磁盤路徑
     * @param data
     *            輸入到FTL中的數據
     * @param response
     *            HttpServletResponse
     * @return
     * @throws TemplateNotFoundException
     * @throws MalformedTemplateNameException
     * @throws ParseException
     * @throws IOException
     * @throws TemplateException
     * @throws DocumentException
     */

    public static ITextRenderer getRender() throws DocumentException, IOException {
        ITextRenderer render = new ITextRenderer();
        String path = getPath();
        // 添加字體,以支持中文
        render.getFontResolver().addFont(path + "fonts/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

        render.getFontResolver().addFont(path + "fonts/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        return render;
    }

    // 獲取要寫入PDF的內容
    public static String getPdfContent(String ftlPath, String ftlName, Object o) throws Exception {
        return useTemplate(ftlPath, ftlName, o);
    }

    // 使用freemarker得到html內容
    public static String useTemplate(String ftlPath, String ftlName, Object o) throws Exception {
        String html = null;
        Template tpl = getFreemarkerConfig(ftlPath).getTemplate(ftlName);
        tpl.setEncoding("UTF-8");
        StringWriter writer = new StringWriter();
        tpl.process(o, writer);
        writer.flush();
        html = writer.toString();
        return html;
    }

    /**
     * 獲取Freemarker配置
     * 
     * @param templatePath
     * @return
     * @throws IOException
     */
    private static Configuration getFreemarkerConfig(String templatePath) throws IOException {
        Configuration config = new Configuration();
        config.setDirectoryForTemplateLoading(new File(templatePath));
        config.setEncoding(Locale.CHINA, "utf-8");
        return config;
    }

    /**
     * 獲取類項目根路徑
     * 
     * @return
     */
    public static String getPath() {
        // return PDFUtil.class.getResource("").getPath().substring(1);
        // //返回類路徑(當前類所在的路徑)
        return PDFUtil.class.getResource("/").getPath().substring(1); // 返回項目根路徑(編譯之後的根路徑)
    }

    public static void main(String[] args) throws Exception {

        String templateName = "off_cnpc_plasthetics";// 需要選用的模板名稱
        String targetPathRoot = "E:/temp/";// 生成pdf的目標位置
        Map<String, Object> map = generateUnitOpenAccountApplicationData();// 構建模板所需數據

        try {
            String path = PDFUtil.getPath();
            
            // System.out.println(path); //項目根路徑
            PDFUtil.generateToFile(path, "templates/" + templateName + ".ftl", path + "/images/", map,
                    targetPathRoot + templateName + ".pdf");
            System.out.println("生成PDF成功!");
            // 要輸出的pdf文件
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("E:/temp/abc2.pdf")));
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            // 將pdf文件先加水印然後輸出
            setWatermark(bos, "E:/temp/off_cnpc_plasthetics.pdf", format.format(cal.getTime()) + "  下載使用人:" + "測試user",
                    16);
            System.out.println("蓋章成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("生成PDF失敗!");
        }

    }

    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName, int permission)
            throws DocumentException, IOException {
        String path = PDFUtil.getPath();
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, bos);
        int total = reader.getNumberOfPages() + 1;
        PdfContentByte content;
        BaseFont base = BaseFont.createFont(path + "fonts/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        PdfGState gs = new PdfGState();
        for (int i = 1; i < total; i++) {
            content = stamper.getOverContent(i);// 在內容上方加水印
            //content = stamper.getUnderContent(i);//在內容下方加水印
            gs.setFillOpacity(0.2f);
            // content.setGState(gs);
            content.beginText();
            content.setColorFill(Color.LIGHT_GRAY);
            content.setFontAndSize(base, 50);
            content.setTextMatrix(70, 200);
            content.showTextAligned(Element.ALIGN_CENTER, "公司內部文件,請注意保密!", 300, 350, 55);
            content.setColorFill(Color.BLACK);
            content.setFontAndSize(base, 8);
            content.showTextAligned(Element.ALIGN_CENTER, "下載時間:" + waterMarkName + "", 300, 10, 0);
            content.endText();

        }
        stamper.close();
    }

    public static Map<String, Object> generateUnitOpenAccountApplicationData() {
     
        Calendar date = Calendar.getInstance();
        String yearString = new Integer(date.get(Calendar.YEAR)).toString();
        String oldYear = yearString.replace(",", "");
        Map<String, Object> map = new HashMap<>();
        map.put("orderId", "測試111111");
        map.put("year", oldYear);
        map.put("month", date.get(Calendar.MONTH) + 1);
        map.put("day", date.get(Calendar.DAY_OF_MONTH));
        return map;
    }

}
 

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