PdfUtil 利用html生成pdf或者pdf模板生产pdf

850 阅读3分钟

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletOutputStream;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.megvii.itdev.mit.base.pojo.dto.EduExperienceDTO;
import com.megvii.itdev.mit.base.pojo.dto.PdfDetailDTO;
import lombok.extern.slf4j.Slf4j;

/***
 * @Author: sunkui
 * @Date: 2021/8/23
 * @Time: 13:57
 * @Description:
 ***/

@Slf4j
public class PdfUtil {
    
    private static String fileName = 
    
    PdfUtil.class.getClassLoader().getResource("simhei.ttf").getPath();

    public static void htmlToPdf(String html, String userId, OutputStream out){
        Document document = null;
        ByteArrayInputStream byteArrayInputStream = null;
        try {
            document = new Document(PageSize.A4, 30, 30, 30, 30);
            document.setMargins(30, 30, 30, 30);
            byteArrayInputStream = new ByteArrayInputStream(html.getBytes("UTF-8"));
            //FileOutputStream outputStream = new FileOutputStream(fileName);
            PdfWriter writer = PdfWriter.getInstance(document,out);
            document.open();
            FontProvider provider = new MyFontProvider();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, byteArrayInputStream,XMLWorkerHelper.class.getResourceAsStream("/default.css"), Charset.forName("UTF-8"), provider);
            document.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != byteArrayInputStream){
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void htmlToPdf(String html, String userId, String rootPath){
        Document document = null;
        ByteArrayInputStream byteArrayInputStream = null;
        try {
            document = new Document(PageSize.A4, 30, 30, 30, 30);
            document.setMargins(30, 30, 30, 30);
            byteArrayInputStream = new ByteArrayInputStream(html.getBytes("UTF-8"));
            String fileName = rootPath.concat(userId).concat(".pdf");
            FileOutputStream outputStream = new FileOutputStream(fileName);
            PdfWriter writer = PdfWriter.getInstance(document,outputStream);
            document.open();
            FontProvider provider = new MyFontProvider();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, byteArrayInputStream,XMLWorkerHelper.class.getResourceAsStream("/default.css"), Charset.forName("UTF-8"), provider);
            document.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != byteArrayInputStream){
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     *  利用模板生成pdf
     * @param o 写入的数据
     * @param out 自定义保存pdf的文件流
     * @param inputStream pdf模板文件流
     */
    public static void fillTemplate(Map<String,Object> o, PdfDetailDTO pdfDetailDTO, ServletOutputStream out, InputStream inputStream) {
        PdfReader reader;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        String filePath = "E:\Megin\ceshi.pdf";
        String finalPath = "E:\Megin\ceshi2.pdf";
        FileOutputStream outputStream;
        try {
            // 读取pdf模板
            outputStream = new FileOutputStream(filePath);
            reader = new PdfReader(inputStream);
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            //黑体
            log.info("字体路径:{}",fileName);
            BaseFont cnHei = BaseFont.createFont(fileName, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(cnHei);
            java.util.Iterator<String> it = form.getFields().keySet().iterator();
            while (it.hasNext()) {
                String name = it.next();
                String value = o.get(name)!=null?o.get(name).toString():null;
                log.info("[name:{},value:{}]",name,value);
                form.setField(name,value);
                //form.set
            }
            //reader.getp
            // 如果为false那么生成的PDF文件还能编辑,一定要设为true
            stamper.setFormFlattening(true);
            stamper.close();
            outputStream.write(bos.toByteArray());
            outputStream.flush();
            outputStream.close();
            bos.close();
            generateFinalPdf(filePath,finalPath,"create",pdfDetailDTO);
        } catch (BadPdfFormatException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void generateFinalPdf(String newPath, String finalPath, String baselineType, PdfDetailDTO pdfDetailDTO) throws Exception {
        FileOutputStream outputStream = new FileOutputStream(finalPath);
        // 读取pdf模板
        PdfReader reader = new PdfReader(newPath);
        reader.getNumberOfPages();
        byte[] pageContent = reader.getPageContent(1);
        log.info("当前页内容:{}",new String(pageContent));
        Rectangle pageSize = reader.getPageSize(1);
        Document document = new Document(pageSize);
        PdfWriter writer = PdfWriter.getInstance(document, outputStream);
        //PdfAcroForm acroForm = writer.getAcroForm();
        //acroForm.get

        document.open();
        PdfContentByte cbUnder = writer.getDirectContent();
        PdfImportedPage pageTemplate = writer.getImportedPage(reader, 1);
        cbUnder.addTemplate(pageTemplate, 0, 0);
        document.newPage();//新创建一页来存放后面生成的表格
        if ("create".equals(baselineType)) {
            //生成表格段落
            Paragraph paragraph = generateEdusTable(pdfDetailDTO.getEdus(),writer);
            document.add(paragraph);
        }
        document.close();
        reader.close();
    }
    /**
     * 生成pdf表格
     * @return
     * @see
     */
    private static Paragraph generateEdusTable(java.util.List<EduExperienceDTO> eduList, PdfWriter writer) throws Exception {
        BaseFont cnHei = BaseFont.createFont(fileName, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        //writer.get
        Font fontChinese = new Font(cnHei, 10.5F, Font.NORMAL);
        Font fontChineseBold = new Font(cnHei, 10.5F, Font.BOLD);
        Paragraph ret = new Paragraph("教育经历", fontChineseBold);
        ret.setSpacingBefore(500);
        PdfPTable tableBox = new PdfPTable(5);
        // 每个单元格占多宽
        tableBox.setWidths(new float[] { 0.3f, 0.2f, 0.2f, 0.1f, 0.1f });
        tableBox.setWidthPercentage(80f);
        tableBox.setTotalWidth(480f);

        // 创建表格格式及内容
        tableBox.addCell(getCell(new Phrase("起止时间", fontChineseBold), false, 1, 1));
        tableBox.addCell(getCell(new Phrase("学校", fontChineseBold), false, 1, 1));
        tableBox.addCell(getCell(new Phrase("专业", fontChineseBold), false, 1, 1));
        tableBox.addCell(getCell(new Phrase("学历", fontChineseBold), false, 1, 1));
        tableBox.addCell(getCell(new Phrase("学位", fontChineseBold), false, 1, 1));
        // 遍历查询出的结果
        for (EduExperienceDTO edu : eduList) {
            tableBox.addCell(getCell(new Phrase(edu.getEduPeriod(), fontChinese), false, 1, 1));
            tableBox.addCell(getCell(new Phrase(edu.getSchoolName(), fontChinese), false, 1, 1));
            tableBox.addCell(getCell(new Phrase(edu.getMajor(), fontChinese), false, 1, 1));
            tableBox.addCell(getCell(new Phrase(edu.getEduType(), fontChinese), false, 1, 1));
            tableBox.addCell(getCell(new Phrase(edu.getDegreeName(), fontChinese), false, 1, 1));
        }
        //PdfContentByte canvas = writer.getDirectContent();
        //PdfContentByte contentUnder = writer.getDirectContentUnder();
        //tableBox.writeSelectedRows(0, -1, 60, 380, canvas);
        ret.add(tableBox);
        return ret;

    }

    //每个cell的格式,合并单元格
    private static PdfPCell getCell(Phrase phrase, boolean yellowFlag, int colSpan, int rowSpan) {
        PdfPCell cells = new PdfPCell(phrase);
        cells.setUseAscender(true);
        cells.setMinimumHeight(20f);
        cells.setHorizontalAlignment(1);
        cells.setVerticalAlignment(5);
        cells.setColspan(colSpan);
        cells.setRowspan(rowSpan);
        cells.setNoWrap(false);
        return cells;
    }




    /***
     *
     * @param o
     * @param templatePath
     * @return
     */
    public static Map<String, String> fillTemplate(String fileName, Map<String,Object> o,String templatePath) {
        Map<String, String> resultMap = new HashMap<>();
        String filePath = "/static/attachments/megin/".concat(fileName);
        FileOutputStream outputStream;
        PdfReader reader;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        try {
            outputStream = new FileOutputStream(filePath);
            // 读取pdf模板
            reader = new PdfReader(templatePath);
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            //PdfPTable table = new PdfPTable(2);
            //table.writeSelectedRows()
            java.util.Iterator<String> it = form.getFields().keySet().iterator();
            while (it.hasNext()) {
                String name = it.next();
                System.out.println(name);
                String value = o.get(name)!=null?o.get(name).toString():null;
                form.setField(name,value);
            }
            // 如果为false那么生成的PDF文件还能编辑,一定要设为true
            stamper.setFormFlattening(true);
            stamper.close();

            Document doc = new Document();
            PdfCopy copy = new PdfCopy(doc, outputStream);
            doc.open();
            PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
            copy.addPage(importPage);
            doc.close();

        } catch (IOException e) {
            System.out.println(e);
        } catch (DocumentException e) {
            System.out.println(e);
        }
        resultMap.put("fileName",fileName);
        resultMap.put("filePath",filePath);
        return resultMap;
    }
}

class MyFontProvider extends XMLWorkerFontProvider {
    //"c:\windows\fonts\simhei.ttf"
    //PdfUtil.class.getClassLoader().getResource("simhei.ttf").getPath();
    private static String fontPath = "/simhei.ttf";
    @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 {
            bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Font font = new Font(bf, size, style, color);
        font.setColor(color);
        return font;
    }
}