java 生成PDF表格,添加页码,加盖水印(包括图片水印和文字水印)

最近公司要求后端实现PDF导出功能,并且还要要求能够加盖水印。网上搜寻了一下,大多帖子比较老旧,并且随着开发包的版本更新,都不能用,所以有了这篇博客。

生成PDF所用到的jar包主要是itext,现在这个包在中央仓库的最新版是5.5.13.1

不过官网主打的确是7版本:点击进入官网地址,好像是要收费的,所以还是用5版本吧

下面是用的jar包和版本,解释一下itextpdf是核心包,itext-asian是为了中文支持,如果不引用该包将无法显示中文

        
            com.itextpdf
            itextpdf
            5.5.13
        
        
            com.itextpdf
            itext-asian
            5.2.0
        

上代码:

public static final String BASE_PDF_PATH = "C:\\Users\\xxx\\Desktop\\";
    
public static  void createDPFTable(String fileName, Map fieldMap, List dataList) {
        Document document = new Document(PageSize.A4);
        document.setMargins(10, 10, 30, 30);
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(BASE_PDF_PATH + fileName + ".pdf");
            PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
            pdfWriter.setPdfVersion(PdfWriter.VERSION_1_7);
            //自定义字体
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bf, 8);
            pdfWriter.setPageEvent(new PageEvent());
            //编辑文档
            document.open();
            Set> entries = fieldMap.entrySet();
            PdfPTable pdfTable = createTable(fieldMap, font);
            if (dataList != null && dataList.size() > 0) {
                //创建数据
                for (T t : dataList) {
                    for (Map.Entry entry : entries) {
                        String value = entry.getValue();
                        Object methodVal = getMethodVal(t.getClass(), t, value);
                        if (methodVal == null) {
                            methodVal = "";
                        }
                        PdfPCell pdfPCell = new PdfPCell(new Phrase(methodVal.toString(), font));
                        pdfPCell.setHorizontalAlignment(Paragraph.ALIGN_CENTER);
                        pdfPCell.setVerticalAlignment(Paragraph.ALIGN_CENTER);
                        pdfTable.addCell(pdfPCell);
                    }
                }
            }
            document.add(pdfTable);
            document.close();
            System.out.println("创建成功!");

        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static PdfPTable createTable(Map fieldMap, Font font) {
        PdfPTable pdfTable = new PdfPTable(fieldMap.size());
        pdfTable.setSpacingBefore(10);
        pdfTable.setHorizontalAlignment(Element.ALIGN_CENTER);
        pdfTable.setSplitRows(false);

        Set> entries = fieldMap.entrySet();
        for (Map.Entry entry : entries) {
            PdfPCell pdfPCell = new PdfPCell(new Phrase(entry.getKey(), font));
            pdfPCell.setHorizontalAlignment(Paragraph.ALIGN_CENTER);
            pdfPCell.setVerticalAlignment(Paragraph.ALIGN_CENTER);
            pdfTable.addCell(pdfPCell);
        }
        return pdfTable;
    }

然后就是添加页码和水印了,因为itext有个pageEvent的概念,意思是在我们生成一个pdf文档的一些时机,我们可以在这些点做一些自己的额外操作。具体做法是建一个类实现PdfPageEventHelper类,并重写里面的方法即可,上代码:

public class PageEvent extends PdfPageEventHelper {

    private PdfTemplate tpl;
    private BaseFont bf;

    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        tpl = writer.getDirectContent().createTemplate(100, 100);
        try {
            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onStartPage(PdfWriter writer, Document document) {
        super.onStartPage(writer, document);
        addTextWaterMark(writer, bf, 50, 0.1f, "传说中的水印");
        //addImageWaterMark(writer, 0.5f, "C:\\Users\\xxx\\Desktop\\waterMark.png");
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        //每一次在页面写完结束后,计算一下页码,
        PdfContentByte cb = writer.getDirectContent();

        String text = "第" + writer.getPageNumber() + " 页,共 ";
        float textSize = bf.getWidthPoint(text, 9);
        float textBase = document.bottom();
        cb.beginText();
        cb.setFontAndSize(bf, 9);

        cb.setTextMatrix(document.left(), textBase);
        cb.showText(text);
        cb.endText();
        cb.addTemplate(tpl, document.left() + textSize, textBase);
    }

    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        //文档关闭后,计算一下总页数
        tpl.beginText();
        tpl.setFontAndSize(bf, 9);
        tpl.setTextMatrix(0, 0);
        tpl.showText((writer.getPageNumber() - 1) + " 页");
        tpl.endText();
    }

    //文字水印
    private static void addTextWaterMark(PdfWriter pdfWriter, BaseFont bf, int fontSize, float fillOpacity, String text) {
        //添加水印
        PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
        contentUnder.beginText();
        contentUnder.setColorFill(BaseColor.BLUE);
        contentUnder.setFontAndSize(bf, fontSize);
        //设置水印透明度
        PdfGState pdfGState = new PdfGState();
        pdfGState.setFillOpacity(fillOpacity);
        contentUnder.setGState(pdfGState);

        Random random = new Random();
        for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 30; initX += 300) {
            for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 30; initY += 250) {
                contentUnder.showTextAligned(Element.ALIGN_CENTER, text, initX, initY, 30);
            }
        }
        contentUnder.endText();
    }
    //图像水印
    private static void addImageWaterMark(PdfWriter pdfWriter, float fillOpacity, String imgUrl) {
        PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
        try {
            Image image = Image.getInstance(imgUrl);
            image.scaleToFit(200, 150);

            PdfGState pdfGState = new PdfGState();
            pdfGState.setFillOpacity(fillOpacity);
            contentUnder.setGState(pdfGState);
            Random random = new Random();

            for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 40; initX += 300) {
                for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 40; initY += 300) {
                    image.setAbsolutePosition(initX, initY);
                    image.setRotationDegrees(30);
                    contentUnder.addImage(image);

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

下面是运行效果:

java 生成PDF表格,添加页码,加盖水印(包括图片水印和文字水印)_第1张图片

你可能感兴趣的:(java)