700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java 生成PDF表格 添加页码 加盖水印(包括图片水印和文字水印)

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

时间:2024-03-16 14:42:04

相关推荐

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

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

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

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

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

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

上代码:

public static final String BASE_PDF_PATH = "C:\\Users\\xxx\\Desktop\\";public static <T> void createDPFTable(String fileName, Map<String, String> fieldMap, List<T> 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<Map.Entry<String, String>> entries = fieldMap.entrySet();PdfPTable pdfTable = createTable(fieldMap, font);if (dataList != null && dataList.size() > 0) {//创建数据for (T t : dataList) {for (Map.Entry<String, String> 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<String, String> fieldMap, Font font) {PdfPTable pdfTable = new PdfPTable(fieldMap.size());pdfTable.setSpacingBefore(10);pdfTable.setHorizontalAlignment(Element.ALIGN_CENTER);pdfTable.setSplitRows(false);Set<Map.Entry<String, String>> entries = fieldMap.entrySet();for (Map.Entry<String, String> 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;@Overridepublic 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();}}@Overridepublic 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");}@Overridepublic 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);}@Overridepublic 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();}}}

下面是运行效果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。