java实现pdf水印详解,支持换行、旋转且样式不会错乱,贼透彻 您所在的位置:网站首页 防伪牌怎么去水印 java实现pdf水印详解,支持换行、旋转且样式不会错乱,贼透彻

java实现pdf水印详解,支持换行、旋转且样式不会错乱,贼透彻

2024-07-16 15:21| 来源: 网络整理| 查看: 265

java实现pdf水印详解,支持换行、旋转且样式不会错乱,贼透彻 业务需求代码实现思路效果图本地代码实现一、前期准备二、pdf水印生成简单样例(基础)三、showTextAligned方法解读四、根据需求实现水印

业务需求

   在客户点击链接评价完后生成相应评价数据的pdf文件,并且添加水印,水印添加完成后进行第三方签名。水印名称为项目名称,字体默认,字号12,颜色浅灰色,水印文字排列为8 * 3(一行3个水印,一页8行),水印30度旋转,且支持文字换行,换行后文字居中。

代码实现思路

   因为是公司项目,为了方便整理成了3步骤实现,第一步生成评价数据的pdf文件,第二步添加水印,第三步进行第三方签名,这篇文章主要分析水印相关的实现和详细步骤拆分,看完自己就可以根据需求定制水印,想放哪儿就放哪儿,怎么好看你就能怎么整。

效果图

在这里插入图片描述 在这里插入图片描述

本地代码实现 一、前期准备 依赖: com.itextpdf itextpdf 5.4.3 com.itextpdf itext-asian 5.2.0 一个pdf文件 二、pdf水印生成简单样例(基础) public static void main(String[] args) throws Exception { ReducePdfTestService reducePdfService = new ReducePdfTestService(); reducePdfService.setPdfWaterMarForFileTest("D:/file/todest/", "test.pdf", "测试水印"); } /** * 给已经输出的pdf文件添加水印 * @param filePath * @param fileName * @param * @throws Exception */ public void setPdfWaterMarForFileTest(String filePath, String fileName , String waterText) throws Exception { // 输入PDF文件路径 String inputFile = filePath + fileName; // 输出PDF文件路径 String outputFile = filePath +"temp_" + fileName; // 创建PdfReader对象读取原始PDF文件 PdfReader reader = new PdfReader(inputFile); // 创建PdfStamper对象,用于添加水印 PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile)); // 用于添加水印的主要对象 PdfContentByte waterMar; // 创建水印字体 BaseFont base = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); // 设置水印透明度 PdfGState gs = new PdfGState(); // 设置填充字体不透明度 gs.setFillOpacity(0.12f); gs.setStrokeOpacity(0.3f); // 获取pdf页数 int n = reader.getNumberOfPages(); // 添加水印到每一页 for (int i = 1; i // 每次增加230px和水印宽度的一半,加水印宽度的一半是让第一个水印距离页面左侧有一些填充,更加美观 float xFloat = x * 230 + (float)(textW / 2); System.out.println("x坐标为 = " + xFloat); // x坐标为 = 24.0 x坐标为 = 254.0 x坐标为 = 484.0 waterMar.showTextAligned(Element.ALIGN_LEFT, waterText, xFloat, (float) textH / 2, 0); } // 设置水印结束 waterMar.endText();

效果图 在这里插入图片描述    之后进行整个页面的水印效果,其实就是在上面的基础上再嵌套一个for循环,动态的改变y的坐标值即可。

// 开始设置水印 waterMar.beginText(); for (int y = 0; y // 每次增加230px和水印宽度的一半,加水印宽度的一半是让第一个水印距离页面左侧有一些填充,更加美观 float xFloat = x * 230 + (float)(textW / 2); System.out.println("x坐标为 = " + xFloat); // 每次增加110px和水印字体高度的2倍,加字体高度2倍也是为了让第一个水印距离页面底部有一些填充 float yFloat = y * 110 + (float) textH * 2; System.out.println("y坐标为 = " + yFloat); waterMar.showTextAligned(Element.ALIGN_LEFT, waterText, xFloat, yFloat, 0); } } // 设置水印结束 waterMar.endText();

效果图 在这里插入图片描述    之后我们悄悄将最后一个参数改为30,对应需求的旋转30度,基本就实现了效果。 在这里插入图片描述

   你以为到这儿就完了吗?其实好戏才刚刚开始    从实际需求出发,现在的写法有很多问题,第一:如果水印字数过多样式会错乱且没有支持换行;第二:代码过于死板,不灵活,假如现在业务说要求字号变大或者旋转角度、对齐方式改变,我们依旧需要动态调整里面的参数,也就是x和y的坐标值,如果要求排列方式变化那就更麻烦了。 在这里插入图片描述    这是水印字体过长时出现的情况,样式错乱,接下来处理换行。    思路:实际上还是对x和y坐标的修改,我们指定一下一行允许展示的最多字数(初版,后期会用宽度进行计算),按照字数进行分割,在加一层for循环即可实现。

分割字符串的方法

public static String[] stringToStringArray(String text, int length) { //检查参数是否合法 if (StringUtils.isEmpty(text)) { return null; } if (length if (i splitArr[i] = text.substring(i * length); } } return splitArr; }

改造的水印方法

// 开始设置水印 waterMar.beginText(); String[] marTextArray = stringToStringArray(waterText, 15); for (int y = 0; y for (int t = 0; t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有