java(springboot)实现给pdf加文字水印

发布时间 2023-06-09 15:16:38作者: 夏威夷8080

使用 Spring Boot 实现给 PDF 文件添加文字水印的示例代码。

这里我们使用 iText 库来实现 PDF 文件的操作。首先需要在 pom.xml 中添加以下依赖:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.1.16</version>
</dependency>

接下来,我们定义一个 Spring Boot 的 Controller,提供一个接口来接收上传的 PDF 文件,并返回加上水印后的文件。具体代码如下:

import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@Controller
@RequestMapping("/api/watermark")
public class WatermarkController {

    @Value("${app.upload.dir}")
    private String uploadDir;

    @PostMapping(value = "/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<byte[]> addWatermark(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "text", defaultValue = "") String text,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        try {
            // 创建 PDF 文件对象
            PdfDocument pdfDoc = new PdfDocument(
                    new PdfReader(file.getInputStream()),
                    new PdfWriter(new ByteArrayOutputStream())
            );

            // 获取 PDF 文件页数
            int pageNumbers = pdfDoc.getNumberOfPages();

            // 遍历每一页,添加水印
            for (int i = 1; i <= pageNumbers; i++) {
                PdfPage page = pdfDoc.getPage(i);
                Rectangle pageSize = page.getPageSize();

                PdfCanvas canvas = new PdfCanvas(page);

                // 设置字体样式
                PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD);
                float fontSize = 50f;
                canvas.setFontAndSize(font, fontSize);

                // 设置文字颜色和透明度
                canvas.setFillColor(ColorConstants.LIGHT_GRAY);
                canvas.setStrokeColor(ColorConstants.LIGHT_GRAY);
                canvas.setStrokeOpacity(0.4f);

                // 计算水印坐标和旋转角度
                float x = (pageSize.getRight() - pageSize.getLeft()) / 2;
                float y = (pageSize.getTop() - pageSize.getBottom()) / 2;
                float angle = -45f;

                // 添加水印
                if (StringUtils.hasText(text)) {
                    canvas.saveState();
                    canvas.beginText();
                    canvas.showTextAligned(new Paragraph(text).setFont(font).setFontSize(fontSize),
                            x, y, TextAlignment.CENTER, angle);
                    canvas.endText();
                    canvas.restoreState();
                }
            }

            // 生成加上水印后的 PDF 文件
            Path savedFilePath = Paths.get(uploadDir, UUID.randomUUID() + ".pdf");
            OutputStream os = new FileOutputStream(savedFilePath.toFile());
            PdfDocument newPdfDoc = new PdfDocument(new PdfWriter(os));
            pdfDoc.copyPagesTo(1, pageNumbers, newPdfDoc);
            newPdfDoc.close();
            pdfDoc.close();

            // 返回加上水印后的 PDF 文件
            byte[] bytes = Files.readAllBytes(savedFilePath);
            return ResponseEntity
                    .ok()
                    .header("Content-Disposition", "attachment; filename=\"watermark.pdf\"")
                    .body(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().build();
        }
    }
}

以上代码中,我们使用 Spring Boot 的注解来定义一个 /api/watermark/add 接口,该接口使用 @PostMapping 来接收上传的 PDF 文件,并将加上水印后的文件返回给客户端。具体实现中,我们使用了 iText 库来对 PDF 文件进行操作:

  1. 遍历 PDF 文件的每一页,将给定文本添加到中心位置。
  2. 生成加上水印的新 PDF 文件,并返回给客户端。

在代码中,还需要注意以下几点:

  1. @Value("${app.upload.dir}") 注解用于从配置文件中读取上传文件保存的目录。
  2. 在添加水印时,我们将文字旋转了 45 度,这是为了使水印更加美观。
  3. 在返回新的 PDF 文件时,我们使用了 Content-Disposition 头来告知客户端该文件应该被下载。

以上就是一个使用 Spring Boot 实现给 PDF 文件添加文字水印的示例代码,希望能对你有所帮助。