【记录】pdf添加水印(文字、图片水印)

2023-01-02 00:00:00 添加 文字 水印

先上效果图 由于透明度设置的比较低,可能看不太清右上角的是文字和图片的水印,图片打码了。

《【记录】pdf添加水印(文字、图片水印)》

《【记录】pdf添加水印(文字、图片水印)》

该实现中有word转pdf的方法,如有需要请移步另一个word转pdf的帖子,小白一个写的比较冗余哈。

pom

	<dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.11</version>
    </dependency>

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

业务逻辑

@Override
    public void loadPdf(HttpServletRequest request, HttpServletResponse response, PdfDTO pdfDTO) throws Exception { 
        String realPath = request.getSession().getServletContext().getRealPath(File.separator);
        long docTime = System.currentTimeMillis();

        //包含doc、docx下载到本地
        if (pdfDTO.getStrUrl().contains(".doc") || pdfDTO.getStrUrl().contains(".docx")) { 

            logger.info("realPath路径为:" + realPath);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String fileAdd = sdf.format(new Date());
            String inputPath = realPath + File.separator + fileAdd + File.separator;
            logger.info("inputPath路径为:" + inputPath);
            File file = new File(inputPath);
            if (!file.exists() && !file.isDirectory()) { 
                file.mkdir();
            }

            long newPdfTime = System.currentTimeMillis();
            String fileName = docTime + ".doc";
            String newPdf = newPdfTime + ".pdf";
            String rePath = inputPath + File.separator + File.separator + fileName;
            String newPdfPath = inputPath + File.separator + File.separator + newPdf;
            //将下载的doc、docx保存到本地
            downloadFile(pdfDTO.getStrUrl(), rePath);
            logger.info("保存的doc路径:" + realPath);

            long l = System.currentTimeMillis();
            //读取本地doc、docx 转换成pdf
            PdfUtil.doc2pdf(rePath, newPdfPath);
            logger.info("doc转pdf生成的新pdf路径:" + newPdfPath);
            long l1 = System.currentTimeMillis();
            logger.info("生成pdf用时为:" + (l1 - l));

            //把转完的pdf打上水印
            // 要输出的pdf文件
            Date date = new Date();
            SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date1 = sdff.format(date);
            String waterPdf = System.currentTimeMillis() + ".pdf";
            String waterPdfPath = inputPath + File.separator + File.separator + waterPdf;
            logger.info("打完水印的路径为:" + waterPdfPath);
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(waterPdfPath)));
            waterMark(bos, newPdfPath, pdfDTO.getType());

            //将打完水印的pdf输出到前台
            downPdf(request, response, waterPdfPath);

            //删除文件夹下所有内容
            deleteDir(inputPath);

            return;
        }

        long l = System.currentTimeMillis();
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1 = simpleDateFormat.format(date);

       /* String outputFilePath = "D:\\b.pdf"; String returnUrl = request.getScheme() + "://" + request.getServletPath() + ":" + request.getServerPort() + request.getContextPath() + "/unload/";*/

        logger.info("realPath路径为:" + realPath);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String fileAdd = sdf.format(new Date());
        String inputPath = realPath + File.separator + fileAdd + File.separator;
        logger.info("inputPath路径为:" + inputPath);
        File file = new File(inputPath);
        if (!file.exists() && !file.isDirectory()) { 
            file.mkdir();
        }

        String fileName = l + ".pdf";
        logger.info("fileName文件名:" + fileName);
        String rePath = inputPath + File.separator + File.separator + fileName;
        logger.info("rePath保存路径以及文件名:" + rePath);
        // 给获取到的pdf添加水印 
        waterMark(new URL(pdfDTO.getStrUrl()), rePath, pdfDTO.getType());
        // 下载pdf
        downPdf(request, response, rePath);
        // 删除之前生成的pdf
        deletePdf(inputPath, fileName);
    }

主要实现

//给PDF添加水印
    //inputFile 文件路径+名称
    //outputFile 添加水印后输出文件保存的路径+名称
    //waterMarkName 添加水印的内容
    public static void waterMark(BufferedOutputStream bos, String input, Integer type) { 
        try { 
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            String format = sdf.format(date);
            //String waterMarkName = type == 1 ? "用印" : "XX管理有限公司" + "\n" + AuthUtil.getUserAccount() + "\n" + format;
            //切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
            PdfReader reader = new PdfReader(input);
            PdfStamper stamper = new PdfStamper(reader, bos);

            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

            PdfGState gs = new PdfGState();
            //gs.setFillOpacity(0.5f);//改透明度
            gs.setStrokeOpacity(0.3f);
            int total = reader.getNumberOfPages() + 1;


            String waterMarkName = "";
            String waterMarkName2 = AuthUtil.getUserAccount();
            if (type == 1) { 
                waterMarkName = "定稿";
            }
            if (type == 2) { 
                waterMarkName = "XX管理有限公司";
            }

            PdfContentByte under;
            // 仅添加一个水印
            if (type == 1) { 
                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.25f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 20);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 80), (height - 40), 0);
                    InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
                    byte[] bytes = inputStream2byte(path);
                    Image image = Image.getInstance(bytes);
                    image.setAbsolutePosition((width - 65),
                            (height - 52)); // set the first background image of the absolute
                    image.scaleToFit(40, 40);
                    under.addImage(image);
                    under.endText();
                }
            }

            if (type == 2) { 
                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 300), (height - 300), 45);
                    //String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
                    InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
                    byte[] bytes = inputStream2byte(path);
                    Image image = Image.getInstance(bytes);
                    image.setAbsolutePosition((width - 495),
                            (height - 475)); // set the first background image of the absolute
                    image.scaleToFit(50, 50);
                    image.setRotationDegrees(45);
                    under.addImage(image);
                    under.endText();
                }

                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName2, (width - 300), (height - 350), 45);
                    under.endText();
                }

                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, format, (width - 295), (height - 400), 45);
                    under.endText();
                }
            }
            //下边这一段可添加多个水印
// Rectangle pageRect = null;
// FontMetrics metrics;
// int interval = -5;
// int textH = 0;
// int textW = 0;
// label.setText(waterMarkName);
// metrics = label.getFontMetrics(label.getFont());
// textH = metrics.getHeight();
// textW = metrics.stringWidth(label.getText());
// for (int i = 1; i < total; i++) { 
// gs.setFillOpacity(0.4f); // 透明度
// pageRect = reader.getPageSizeWithRotation(i);
// under = stamper.getOverContent(i);//在内容上方加水印
// //under = stamper.getUnderContent(i);//在内容下方加水印
// under.saveState();
// under.setGState(gs);
// under.beginText();
// under.setFontAndSize(base, 25);
//
// // 水印文字成30度角倾斜
// for (int height = interval + textH; height < pageRect.getHeight();
// height = height + textH * 15) { 
// for (int width = interval + textW; width < pageRect.getWidth() + textW;
// width = width + textW * 1) { 
// under.showTextAligned(Element.ALIGN_LEFT
// , waterMarkName, width - textW,
// height - textH, 30);
// }
// }
// // 添加水印文字
// under.endText();
// }
            stamper.close();
            reader.close();
        } catch (Exception e) { 
            e.printStackTrace();
        }
    }

该方法和上面实现基本一致,传参不同

//给PDF添加水印
    //inputFile 文件路径+名称
    //outputFile 添加水印后输出文件保存的路径+名称
    //waterMarkName 添加水印的内容
    public static void waterMark(URL inputFile, String outputFile, Integer type) { 
        try { 
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            String format = sdf.format(date);
            //切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
            PdfReader reader = new PdfReader(inputFile);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));

            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

            PdfGState gs = new PdfGState();
            //gs.setFillOpacity(0.5f);//改透明度
            gs.setStrokeOpacity(0.3f);
            int total = reader.getNumberOfPages() + 1;

            JLabel label = new JLabel();

            String waterMarkName = "";
            String waterMarkName2 = AuthUtil.getUserAccount();
            if (type == 1) { 
                waterMarkName = "定稿";
            }
            if (type == 2) { 
                waterMarkName = "XX管理有限公司";
            }
            /*label.setText(waterMarkName);*/

            PdfContentByte under;
            // 仅添加一个水印
            if (type == 1) { 
                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.25f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 20);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 80), (height - 40), 0);
                    //String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
                    InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
                    byte[] bytes = inputStream2byte(path);
                    Image image = Image.getInstance(bytes);
                    image.setAbsolutePosition((width - 65),
                            (height - 52)); // set the first background image of the absolute
                    image.scaleToFit(40, 40);
                    under.addImage(image);
                    under.endText();
                }
            }

            if (type == 2) { 
                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 300), (height - 300), 45);
                    //String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
                    InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
                    byte[] bytes = inputStream2byte(path);
                    Image image = Image.getInstance(bytes);
                    image.setAbsolutePosition((width - 495),
                            (height - 475)); // set the first background image of the absolute
                    image.scaleToFit(50, 50);
                    image.setRotationDegrees(45);
                    under.addImage(image);
                    under.endText();
                }

                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, waterMarkName2, (width - 300), (height - 350), 45);
                    under.endText();
                }

                for (int i = 1; i < total; i++) { 
                    Rectangle pageSize = reader.getPageSize(i);
                    float height = pageSize.getHeight();
                    float width = pageSize.getWidth();
                    under = stamper.getOverContent(i);// 在内容上方加水印
                    //under = stamper.getUnderContent(i);//在内容下方加水印
                    gs.setFillOpacity(0.4f);//改透明度
                    under.setGState(gs);
                    under.beginText();
                    under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
                    under.setFontAndSize(base, 30);//改水印文字大小
                    under.setTextMatrix(70, 200);
                    //后3个参数,x坐标,y坐标,角度
                    under.showTextAligned(Element.ALIGN_CENTER, format, (width - 295), (height - 400), 45);
                    under.endText();
                }
            }

            //下边这一段可添加多个水印
// Rectangle pageRect = null;
// FontMetrics metrics;
// int interval = -5;
// int textH = 0;
// int textW = 0;
// label.setText(waterMarkName);
// metrics = label.getFontMetrics(label.getFont());
// textH = metrics.getHeight();
// textW = metrics.stringWidth(label.getText());
// for (int i = 1; i < total; i++) { 
// gs.setFillOpacity(0.4f); // 透明度
// pageRect = reader.getPageSizeWithRotation(i);
// under = stamper.getOverContent(i);//在内容上方加水印
// //under = stamper.getUnderContent(i);//在内容下方加水印
// under.saveState();
// under.setGState(gs);
// under.beginText();
// under.setFontAndSize(base, 25);
//
// // 水印文字成30度角倾斜
// for (int height = interval + textH; height < pageRect.getHeight();
// height = height + textH * 15) { 
// for (int width = interval + textW; width < pageRect.getWidth() + textW;
// width = width + textW * 1) { 
// under.showTextAligned(Element.ALIGN_LEFT
// , waterMarkName, width - textW,
// height - textH, 30);
// }
// }
// // 添加水印文字
// under.endText();
// }
            stamper.close();
            reader.close();
        } catch (Exception e) { 
            e.printStackTrace();
        }
    }

帮助工具类

/** * 下载文件到本地 * * @param fileUrl 远程地址 * @param fileLocal 本地路径 * @throws Exception */
    public void downloadFile(String fileUrl, String fileLocal) throws Exception { 
        URL url = new URL(fileUrl);
        HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
        urlCon.setConnectTimeout(6000);
        urlCon.setReadTimeout(6000);
        int code = urlCon.getResponseCode();
        if (code != HttpURLConnection.HTTP_OK) { 
            throw new Exception("文件读取失败");
        }

        //读文件流
        DataInputStream in = new DataInputStream(urlCon.getInputStream());
        DataOutputStream out = new DataOutputStream(new FileOutputStream(fileLocal));
        byte[] buffer = new byte[2048];
        int count = 0;
        while ((count = in.read(buffer)) > 0) { 
            out.write(buffer, 0, count);
        }
        out.close();
        in.close();
    }
//input转byte[]
    public static byte[] inputStream2byte(InputStream inputStream) throws IOException { 
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while ((rc = inputStream.read(buff, 0, 100)) > 0) { 
            byteArrayOutputStream.write(buff, 0, rc);
        }
        return byteArrayOutputStream.toByteArray();
    }
// 下载加水印之后的文件
    public void downPdf(HttpServletRequest httpRequest, HttpServletResponse response, String fileName)
            throws IOException { 

        long l = System.currentTimeMillis();
        String filename = AuthUtil.getUserId() + l + ".pdf";
        File file = new File(fileName);
        // 文件存在才下载
        if (file.exists()) { 
            OutputStream out = null;
            FileInputStream in = null;
            try { 
                // 读取要下载的内容
                in = new FileInputStream(file);

                // 告诉浏览器下载的方式以及一些设置
                // 解决文件名乱码问题,获取浏览器类型,转换对应文件名编码格式,IE要求文件名必须是utf-8, firefox要求是iso-8859-1编码
                String agent = httpRequest.getHeader("user-agent");
                if (agent.contains("FireFox")) { 
                    filename = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
                } else { 
                    filename = URLEncoder.encode(filename, "UTF-8");
                }
                // 设置下载文件的mineType,告诉浏览器下载文件类型
                String mineType = httpRequest.getServletContext().getMimeType(filename);
                response.setContentType(mineType);
                // 设置一个响应头,无论是否被浏览器解析,都下载
                response.setHeader("Content-disposition", "attachment; filename=" + filename);
                // 将要下载的文件内容通过输出流写到浏览器
                out = response.getOutputStream();
                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = in.read(buffer)) > 0) { 
                    out.write(buffer, 0, len);
                }
            } catch (IOException e) { 
                e.printStackTrace();
            } finally { 
                if (out != null) { 
                    out.close();
                }
                if (in != null) { 
                    in.close();
                }
            }
        }
    }
//删除文件加下所有内容
    public static void deleteDir(String path) { 
        File file = new File(path);
        if (!file.exists()) { //判断是否待删除目录是否存在
            System.err.println("The dir are not exists!");
            return;
        }

        String[] content = file.list();//取得当前目录下所有文件和文件夹
        for (String name : content) { 
            File temp = new File(path, name);
            if (temp.isDirectory()) { //判断是否是目录
                deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
                temp.delete();//删除空目录
            } else { 
                if (!temp.delete()) { //直接删除文件
                    System.err.println("Failed to delete " + name);
                }
            }
        }
        return;
    }
//下载后删除该pdf,否则会造成文件越来越多
    private void deletePdf(String inputPath, String fileName) { 
        File file = new File(inputPath);
        if (file.isDirectory()) { 
            String[] dirPathList = file.list();
            for (int i = 0; i < Objects.requireNonNull(dirPathList).length; i++) { 
                String filePath = inputPath + File.separator + dirPathList[i];
                File fileDelete = new File(filePath);
                if (Func.equals(fileDelete.getName(), fileName)) { 
                    fileDelete.delete();
                }
                deletePdf(filePath, fileName);
            }
        }
    }
    原文作者:Dooooooooooong
    原文地址: https://blog.csdn.net/weixin_46697618/article/details/121693704
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章