java HTML+freemarker 生成PDF

1:pom中添加依赖

<dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf</artifactId>
            <version>9.1.5</version>
        </dependency>

        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf-itext5</artifactId>
            <version>9.1.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.6</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
        </dependency>
   2:新建HTML模板,放在项目根目录下
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716171747921.png#pic_center)

3:新建个工具类:pdfUtils

	import com.clife.pension.model.hr.MonthPrintVo;
import com.clife.pension.vo.FeeDetailInfoVo;
import com.clife.pension.vo.MonthPrintPDFVo;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class PDFUtil {

    private String tempFilePath;
    private String tempFileName;

    private static final String FONT = "simhei.ttf";

    public PDFUtil() {}

    public PDFUtil(String tempFilePath, String tempFileName) {
        this.tempFilePath=tempFilePath;
        this.tempFileName=tempFileName;
    }

    public String getTempFilePath() {
        return tempFilePath;
    }
    public void setTempFilePath(String tempFilePath) {
        this.tempFilePath = tempFilePath;
    }
    public String getTempFileName() {
        return tempFileName;
    }
    public void setTempFileName(String tempFileName) {
        this.tempFileName = tempFileName;
    }



    public static void main(String[] args) {


        String name = "pdf.html";
        PDFUtil pdfUtil = new PDFUtil(PathUtil.getCurrentPath(),name);
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("printTime","2021-07-08");
        paraMap.put("billTime","2021-07");
        paraMap.put("customerName","ZCS");
        paraMap.put("context","更好地发给");
        paraMap.put("projectName","十多个都是废话");
        paraMap.put("src","http://skintest.hetyj.com/30748/36c81a06957684e605c813517eea7d6d.png");




        List<MonthPrintPDFVo> monthFeeList = new ArrayList<>();
        MonthPrintPDFVo month = new MonthPrintPDFVo("床位费","180");
        MonthPrintPDFVo month1 = new MonthPrintPDFVo("洗衣机","50");
        monthFeeList.add(month1);
        monthFeeList.add(month);

        List<MonthPrintPDFVo> cardFeeList = new ArrayList<>();
        MonthPrintPDFVo month3 = new MonthPrintPDFVo("西红柿炒蛋","180");
        cardFeeList.add(month3);

        List<MonthPrintVo> foodFeeList = new ArrayList<>();

        List<MonthPrintVo> serviceFeeList = new ArrayList<>();
        List<MonthPrintVo> waterElectricityFeeList = new ArrayList<>();


        paraMap.put("monthFeeList",monthFeeList);
        paraMap.put("cardFeeList",cardFeeList);
        paraMap.put("foodFeeList",foodFeeList);
        paraMap.put("serviceFeeList",serviceFeeList);
        paraMap.put("waterElectricityFeeList",waterElectricityFeeList);
        paraMap.put("accountInfoList",new ArrayList<>());
        paraMap.put("chineseMoney","一百");
        paraMap.put("totalFee","100");
        paraMap.put("workerName","开个票");

        List<FeeDetailInfoVo> items = new ArrayList<>();

        List<String> oldResPath = new ArrayList<String>();

        FeeDetailInfoVo student = new FeeDetailInfoVo("月费用(总计)","50");
        FeeDetailInfoVo student1 = new FeeDetailInfoVo("餐厅一卡通(总计)","90");
        items.add(student);
        items.add(student1);

        paraMap.put("stu",items);


        try {
            String htmlPath = pdfUtil.fillTemplate2Html(paraMap,System.currentTimeMillis()+"");
            Html2Pdf html2Pdf = new Html2Pdf();
            String uploadfile = html2Pdf.excute(htmlPath);
            System.out.println(uploadfile);

            String zipName = "yuezhangd" + ZipUtil.dateToString();

            String newResPath = PathUtil.getCurrentPath() + "/" + zipName; // 生成的文件夹名

            oldResPath.add(uploadfile);


           
            String zipPath = newResPath + ".zip"; 
            ZipUtil.copyResource(oldResPath, newResPath); 
            ZipUtil.createZip(newResPath, zipPath);

/*
            for (String s : oldResPath) {
                ZipUtil.deleteFile( new File(s) );
            }*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
     * 填充模板
     * @param paramMap
     * @throws Exception
     */
    public  String  fillTemplate(Map<String, Object> paramMap,String pdfName) throws Exception {
        File modelFile = new File(tempFilePath);
        if(!modelFile.exists()) {
            modelFile.mkdirs();
        }
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setDirectoryForTemplateLoading(modelFile);
        configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_23));
        configuration.setDefaultEncoding("UTF-8");   //这个一定要设置,不然在生成的页面中 会乱码
        //获取或创建一个模版。
        Template template = configuration.getTemplate(tempFileName);

        StringWriter stringWriter = new StringWriter();
        BufferedWriter writer = new BufferedWriter(stringWriter);
        template.process(paramMap, writer); //把值写进模板

        String htmlStr = stringWriter.toString();
        writer.flush();
        writer.close();

        String tmpPath = PathUtil.getCurrentPath() + "/temp";
        File tmepFilePath = new File(tmpPath);
        if (!tmepFilePath.exists()) {
            tmepFilePath.mkdirs();
        }
        String  tmpFileName =pdfName+".pdf";
        String outputFile = tmpPath + File.separatorChar + tmpFileName;
        FileOutputStream outFile = new FileOutputStream(outputFile);
        createPDFFile(htmlStr, outFile);
        logger.info("PDF Path Is {}",outputFile);

     //  createPdf(htmlStr,outputFile);
        return outputFile;
    }

    public  String  fillTemplate2Html(Map<String, Object> paramMap,String htmlName) throws Exception {
        File modelFile = new File(tempFilePath);
        if(!modelFile.exists()) {
            modelFile.mkdirs();
        }
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setDirectoryForTemplateLoading(modelFile);
        configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_23));
        configuration.setDefaultEncoding("UTF-8");   //这个一定要设置,不然在生成的页面中 会乱码
        //获取或创建一个模版。
        Template template = configuration.getTemplate(tempFileName);

        StringWriter stringWriter = new StringWriter();
        BufferedWriter writer = new BufferedWriter(stringWriter);
        template.process(paramMap, writer); //把值写进模板

        String htmlStr = stringWriter.toString();
        writer.flush();
        writer.close();

        String tmpPath = PathUtil.getCurrentPath() + "/temp";
        File tmepFilePath = new File(tmpPath);
        if (!tmepFilePath.exists()) {
            tmepFilePath.mkdirs();
        }
        String  tmpFileName =htmlName+".html";
        String outputFile = tmpPath + "/" + tmpFileName;

        createdHtmlTemplate(htmlStr,outputFile);

        return outputFile;
    }


    public  String  fillTemplate(Map<String, Object> paramMap,String pdfName, ZipOutputStream zipOut) throws Exception {
        File modelFile = new File(tempFilePath);
        if(!modelFile.exists()) {
            modelFile.mkdirs();
        }
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setDirectoryForTemplateLoading(modelFile);
        configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_23));
        configuration.setDefaultEncoding("UTF-8");   //这个一定要设置,不然在生成的页面中 会乱码
        //获取或创建一个模版。
        Template template = configuration.getTemplate(tempFileName);

        StringWriter stringWriter = new StringWriter();
        BufferedWriter writer = new BufferedWriter(stringWriter);
        template.process(paramMap, writer); //把值写进模板

        String htmlStr = stringWriter.toString();
        writer.flush();
        writer.close();

        String tmpPath =PathUtil.getCurrentPath() + "/temp";
        File tmepFilePath = new File(tmpPath);
        if (!tmepFilePath.exists()) {
            tmepFilePath.mkdirs();
        }
        String  tmpFileName =pdfName+".pdf";
        String outputFile = tmpPath + File.separatorChar + tmpFileName;
       /* FileOutputStream outFile = new FileOutputStream(outputFile);
        createPDFFile(htmlStr, outFile);*/
        logger.info("PDF Path Is {}",outputFile);

        createPdf(htmlStr,outputFile,zipOut);
        return outputFile;
    }


    /**
     * 根据HTML字符串创建PDF文件
     * @param htmlStr
     * @param os
     * @throws Exception
     */
    private  void createPDFFile(String htmlStr, OutputStream os) throws Exception{
        htmlStr.trim();
        ByteArrayInputStream bais = new ByteArrayInputStream(htmlStr.getBytes("UTF-8"));
        Document document = new Document();
        try {
            PdfWriter writer = PdfWriter.getInstance(document, os);
            document.open();
            FontProvider  provider = new FontProvider();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, bais, Charset.forName("UTF-8"),provider);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }finally {
            try {
                document.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                bais.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void createPdf(String content,String dest) throws IOException, com.lowagie.text.DocumentException {
        ITextRenderer render = new ITextRenderer();
        ITextFontResolver fontResolver = render.getFontResolver();
        fontResolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        // 解析html生成pdf
        render.setDocumentFromString(content);
        //解决图片相对路径的问题
       // render.getSharedContext().setBaseURL(LOGO_PATH);
        render.layout();
        render.createPDF(new FileOutputStream(dest));
    }

    public static void createPdf(String content,String dest,ZipOutputStream zipOut) throws IOException, com.lowagie.text.DocumentException {
        ITextRenderer render = new ITextRenderer();
        ITextFontResolver fontResolver = render.getFontResolver();
        fontResolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        // 解析html生成pdf
        render.setDocumentFromString(content);
        //解决图片相对路径的问题
       // render.getSharedContext().setBaseURL(LOGO_PATH);
        render.layout();

        File file = new File(dest);
        FileOutputStream os = new FileOutputStream(file);
        render.createPDF(os);
        os.flush();
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] b = new byte[1024*10];// 相当于我们的缓存
        String[] split = dest.split("/");
        int length = split.length;
        zipOut.putNextEntry(new ZipEntry(split[length-1]));
        int read = fileInputStream.read(b);
        while (read != 0){
            zipOut.write(b,0,read);
            read = fileInputStream.read(b);
        }
        fileInputStream.close();
    }




    public static void html2pdf(String htmlFile, String pdfFile, String chineseFontPath) throws com.lowagie.text.DocumentException {
        // step 1
        String url;
        OutputStream os = null;
        try {
            url = new File(htmlFile).toURI().toURL().toString();
            os = new FileOutputStream(pdfFile);
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocument(url);
            // 解决中文不显示问题
            ITextFontResolver fontResolver = renderer.getFontResolver();
            fontResolver.addFont(chineseFontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            renderer.layout();
            renderer.createPDF(os);
        } catch (MalformedURLException e) {
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if(os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                }
            }
        }
    }






    /**
     *
     * 字体
     *
     */
    private  class FontProvider extends XMLWorkerFontProvider {

        @Override
        public Font getFont(final String fontname, final String encoding,
                            final boolean embedded, final float size, final int style,
                            final BaseColor color) {
            BaseFont bf = null;
            try {
             //   BaseFont.createFont( "/simsun.ttf",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED)
                bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
               // bf = BaseFont.createFont("./static/simhei.ttf",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Font font = new Font(bf, size, style, color);

            font.setColor(color);
            return font;
        }
    }
    /**
     * 生成html模板
     * @param content
     * @return
     */
    public String createdHtmlTemplate(String content,String htmlPath){
//        String fileName = tempFilePath + "/" + tempFileName;
        String fileName = htmlPath;

        try{
            File file = new File(tempFilePath);
            if(!file.isDirectory()) {
                file.mkdir();
            }
            file = new File(fileName);
            if(!file.isFile()) {
                file.createNewFile();
            }
            //打开文件
            PrintStream printStream = new PrintStream(new FileOutputStream(fileName));

            //将HTML文件内容写入文件中
            printStream.println(content);
            printStream.flush();
            printStream.close();
           logger.info("生成html模板成功!");
        }catch(Exception e){
            e.printStackTrace();
        }
        return fileName;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值