Java 给pdf 添加水印

一、itextpdf
1、依赖:

  
            org.apache.pdfbox
            pdfbox
            2.0.13
        



   
            com.itextpdf
            itext-asian
            5.2.0
        
        
            com.itextpdf
            itextpdf
            5.5.9
        

2、工具类:

package com.foresealife.lams.common.util;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

import java.io.*;

public class PdfWatermarkUtil {
    File file = new File("D:\\contractRelationTemplate\\test.pdf");

// .pdfbox 方法,, 不能添加中文水印,,。。。
    public OutputStream test() throws IOException{
        // 画水印
        try (PDDocument doc = PDDocument.load(file)) {
            int count = doc.getNumberOfPages();
            for (int i = 0; i < count; i++) {
                PDPage page = doc.getPage(i);
                PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND,
                        true, true);
                PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
                r0.setNonStrokingAlphaConstant(0.2f);
                r0.setAlphaSourceFlag(true);
                cs.setGraphicsStateParameters(r0);
                cs.setNonStrokingColor(200, 0, 0);
                for (int m = 0; m < 3; m++) {
                    for (int n = 0; n < 3; n++) {
                        cs.beginText();
                        cs.setFont(PDType1Font.HELVETICA_OBLIQUE, 33);
                        cs.setTextMatrix(Matrix.getRotateInstance(-50, 230 * m + (float) 60, 270 * n + (float) 100));
                        cs.showText("USE胡R");
                        cs.endText();
                    }
                }
                cs.close();
            }
            OutputStream os = new ByteArrayOutputStream();
            doc.save(os);

            return  os;
            //doc.save("D:\\software\\tyest1.pdf");
        }
    }

    /**
    * itextpdf 方法, 可以添加中文水印
     * 中间或者两边水印
     * @param bos   添加完水印的输出
     * @param input 原PDF文件输入
     * @param word  水印内容
     * @param model 水印添加位置1中间,2两边
     */
    public static void setWatermark(ByteArrayOutputStream bos, InputStream input, String word, int model) {
        PdfReader reader = null;
        try {
            reader = new PdfReader(input);
            PdfStamper stamper = new PdfStamper(reader, bos);
            PdfContentByte content;
            // 创建字体,第一个参数是字体路径,itext有一些默认的字体比如说:1
             BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            //2  BaseFont base = BaseFont.createFont("/msyh.ttf", BaseFont.IDENTITY_H,
            //         BaseFont.EMBEDDED);
            //这个是为了解决linux服务器,水印乱码问题,如果是windows服务器,用第一个就可以。
            // 需要指定的字体,用第2,3个写法,在resources文件夹下放置对应字体就行。
            // 3
            //            BaseFont base = BaseFont.createFont("/simhei.ttf", BaseFont.IDENTITY_H,
            //                    BaseFont.EMBEDDED);

            PdfGState gs = new PdfGState();
            // 获取PDF页数
            int total = reader.getNumberOfPages();
            // 遍历每一页
            for (int i = 0; i < total; i++) {
                // 页宽度
                float width = reader.getPageSize(i + 1).getWidth();
                // 页高度
                float height = reader.getPageSize(i + 1).getHeight();
                // 内容
                content = stamper.getOverContent(i + 1);
                //开始写入文本
                content.beginText();
                //水印透明度
                gs.setFillOpacity(0.2f);
                content.setGState(gs);
                content.setColorFill(BaseColor.RED);
                //设置字体的输出位置
                content.setTextMatrix(70, 200);

                if (model == 1) {
                    //平行居中的3条水印
                    //字体大小
                    content.setFontAndSize(base, 50);
                    //showTextAligned 方法的参数分别是(文字对齐方式,位置内容,输出水印X轴位置,Y轴位置,旋转角度)
                    content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 650, 30);
                    content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 400, 30);
                    content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 150, 30);
                } else {
                    // 左右两边个从上到下4条水印
                    // 水印旋转度数
                    float rotation = 30;
                    content.setFontAndSize(base, 20);
                    content.showTextAligned(Element.ALIGN_LEFT, word, 20, height - 50, rotation);
                    content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 * 3 - 50, rotation);
                    content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 2 - 50, rotation);
                    content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 - 50, rotation);

                    content.setFontAndSize(base, 22);
                    content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height - 50, rotation);
                    content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 * 3 - 50, rotation);
                    content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 2 - 50, rotation);
                    content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 - 50, rotation);
                }
                //结束写入文本
                content.endText();
                //要打图片水印的话
                //Image image = Image.getInstance("c:/1.jpg");
                //content.addImage(image);
            }
            stamper.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }

}

3、Controller 层使用工具类

 // 使用 pdfbox   打印水印 并在浏览器下载
@RequestMapping("/api/test")
    public void test(HttpServletRequest request, HttpServletResponse response) throws IOException{
        PdfWatermarkUtil pdfWatermarkUtil = new PdfWatermarkUtil();
        ByteArrayOutputStream out  = (ByteArrayOutputStream)pdfWatermarkUtil.test();
        ByteArrayInputStream inStream = new ByteArrayInputStream(out.toByteArray());
        RequestUtils.testSupport(request,response,"fileName.pdf");

        byte[] b = new byte[2048];
        int len;
        try {
            while ((len = inStream.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //  response.getOutputStream().write(out.toByteArray());
    }

// 使用 itextpdf  打印水印,并在浏览器下载
    @RequestMapping("/api/getWaterMarkt")
    public void getWaterMarkt(@RequestParam("id") long id, HttpServletRequest request, HttpServletResponse response) throws IOException{
       String path = "E/fileName.pdf";
        File file = new File(path);
        InputStream inputStream = new FileInputStream(file);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PdfWatermarkUtil.setWatermark(out, inputStream, "中文", 1);
        RequestUtils.downloadSupport(request,response,"fileName.pdf");
        response.getOutputStream().write(out.toByteArray());
        out.close();
    }

====================================================================================================================================================================================================================================================================================

 public static void testSupport(HttpServletRequest request, HttpServletResponse response, String formFileName) throws IOException {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent != null && (userAgent.contains("MSIE") || userAgent.contains("Trident"))) {
            // 针对IE或者以IE为内核的浏览器:
            formFileName = java.net.URLEncoder.encode(formFileName, "UTF-8");
        } else {
            // 非IE浏览器的处理:
            formFileName = new String(formFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", formFileName));
        response.setCharacterEncoding("UTF-8");
    }
// 写入流

    public static void intSupport(HttpServletRequest request, HttpServletResponse response, File file) throws IOException {
        ServletOutputStream os = null;
        BufferedOutputStream out = null;
        byte[] b = new byte[1024];
        try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
            long pos = headerSetting(request, response, file);
            os = response.getOutputStream();
            out = new BufferedOutputStream(os);
            raf.seek(pos);
            int n = 0;
            while ((n = raf.read(b, 0, 1024)) != -1) {
                out.write(b, 0, n);
            }
            out.flush();
        }

参考有关文章:https://www.cnblogs.com/woshuaile/p/11943874.html

你可能感兴趣的:(文件下载)