一、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