PDF加水印的各种方法
一、Adobe Acrobat JavaScript
1、直接加文字:
this.addWatermarkFromText({
cText: “中华人民共和国”,
nTextAlign: app.constants.align.right,
nHorizAlign: app.constants.align.right,
nVertAlign: app.constants.align.top,
nHorizValue: -72, nVertValue: -72
});
2、将某个水印文件加入到PDF中
this.addWatermarkFromFile({
cDIPath: “/C/watermark.pdf”,
nHorizAlign: app.constants.align.left,
nVertAlign: app.constants.align.top,
nHorizValue: 144, nVertValue: -72,
nRotation: 45
});
这两种方法速度极快,操作PDF资源占用极小, 而且支持任何东西方语言。当然还有很多细节问题,例如字体等等,具体用法可参阅Adobe Acrobat Scripting development http://www.adobe.com/devnet/acrobat/pdfs/js_api_reference.pdf
二、用java开源项目itextpdf来实现
下载itext 5.4.1,地址:http://itextpdf.com/download.php
import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.BaseColor; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; public static final String CHARACTOR_FONT_CH_FILE = "SIMHEI.TTF"; //黑体常规 public static void AddWaterMark(String filename,String outPutFile,String waterText, String pdfTitle,String Subject,String Keywords,String Creator, String Author) throws DocumentException,IOException{ PdfReader.unethicalreading = true; // 待加水印的文件 PdfReader reader = new PdfReader(filename); // 加完水印的文件 PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outPutFile)); HashMap<STRING, String> info = reader.getInfo(); info.put("Title", pdfTitle); info.put("Subject", Subject); info.put("Keywords", Keywords); info.put("Creator", Creator); info.put("Author", Author); stamper.setMoreInfo(info); int total = reader.getNumberOfPages() + 1; PdfContentByte content; // 设置字体 BaseFont base = BaseFont.createFont(CHARACTOR_FONT_CH_FILE,BaseFont.IDENTITY_H, BaseFont.EMBEDDED); int j = waterText.length(); // 文字长度 char c = 0; int high = 0;// 高度 // 循环对每页插入水印 for (int i = 1; i < total; i++) { // 水印的起始 high = 500; content = stamper.getUnderContent(i); // 开始 content.beginText(); // 设置颜色 content.setColorFill(BaseColor.RED); // 设置字体及字号 content.setFontAndSize(base, 18); // 设置起始位置 content.setTextMatrix(0, 0); // 开始写入水印 for (int k = 0; k < j; k++) { content.setTextRise(14); c = waterText.charAt(k); // 将char转成字符串 content.showText(c + ""); high -= 5; } content.endText(); } stamper.close(); }
方法三:利用Apache pdfbox实现,下载地址:http://pdfbox.apache.org/
引入pdfbox相应包,略
public static void main(String args[]){ try{ PDDocument document = PDDocument.load(musiqueFileName); List<?> pages = doc.getDocumentCatalog().getAllPages(); PDPage page = (PDPage) pages.get(0); //给第一页加水印,如果需要全部加,那么循环即可 //创建有个输出流,注意第3个参数必须为true, PDPageContentStream contentStream = new PDPageContentStream(document, page,true,true); //加文字水印 contentStream.beginText(); contentStream.setFont( PDType1Font.TIMES_ITALIC, 12f ); contentStream.moveTextPositionByAmount( 10,10 ); String msg = "Hello World"; contentStream.drawString(msg); contentStream.endText(); //加图片水印 String image = "D:/img.jpg"; PDXObjectImage ximage = null; if( image.toLowerCase().endsWith( ".jpg" ) ) { ximage = new PDJpeg(document, new FileInputStream( image ) ); } else if (image.toLowerCase().endsWith(".tif") || image.toLowerCase().endsWith(".tiff")) { ximage = new PDCcitt(document, new RandomAccessFile(new File(image),"r")); } else { throw new IOException( "Image type not supported:" + image ); } contentStream.drawImage( ximage, 0, 0); contentStream.close(); //这一句很重要,不关闭将无法写入 document.save("C:/lucene/Test.pdf"); document.close(); } catch (Exception e){ System.out.println(e.getMessage()); } }
pdfbox操作PDF的功能极其强大,并且是开源项目,但目前对中文字体的支持不理想,它在和lucene结合方面尤其出色!具体可参阅相关API。
当然对于纯PDF处理,我仍然推荐使用Acrobat Scripting,它的效率之快令人叹服!而且可以查阅Acrobat SDK,可以窥测到PDF最底层的东西