700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java实现对pdf文件压缩 拆分 修改水印 添加水印

java实现对pdf文件压缩 拆分 修改水印 添加水印

时间:2019-04-06 01:30:10

相关推荐

java实现对pdf文件压缩 拆分 修改水印 添加水印

最近要实现一个文件上传,并且在线预览上传文件的功能,设计思路是:把上传的文件通过openoffice转成pdf文件,并将pdf文件以流的形式返回到浏览器,由于上传的部分文件过大,转成pdf后传回前端浏览器需要的时间太长会找出接口超时问题,故需要对转化后的pdf文件进行压缩,分割再分页传回到前台。

在网上看了很多对pdf文件进行操作文档后,收集整理了4个好用代码片段,希望对需要的人有用处吧。

1.java实现对pdf文件压缩:

引用的maven坐标

<!--文件压缩--><dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId><version>18.2</version></dependency>

整理的代码片段

package tvap.pdfutil;import com.aspose.pdf.Document;import tvap.pdfutil.util.DateUtil;/**pdf文件压缩* @author liyuliang* @date /7/14*/public class PdfZipUtil {public static void main(String[] args) {String inputFile = "D:\\opt\\jenkins\\gccc.pdfutil";String outputFile = "D:\\opt\\jenkins\\gccc-opt2.pdfutil";System.out.println(DateUtil.getCurrentTime());optimize(inputFile, outputFile);System.out.println(DateUtil.getCurrentTime());}public static void optimize(String source, String target) {Document doc = new Document(source);//设置压缩属性Document.OptimizationOptions opt = new Document.OptimizationOptions();//删除PDF不必要的对象opt.setRemoveUnusedObjects(true);//链接重复流opt.setLinkDuplcateStreams(false);//删除未使用的流opt.setRemoveUnusedStreams(false);//删除不必要的字体// opt.setUnembedFonts(true);//压缩PDF中的图片opt.setCompressImages(true);//图片压缩比, 0 到100可选,越低压缩比越大opt.setImageQuality(10);doc.optimizeResources(opt);//优化web的PDF文档doc.optimize();doc.save(target);doc.close();}}

进行pdf文件压缩后,pdf文件顶部会有水印,"Evaluation Only. Created with Aspose.PDF. Copyright 2002- Aspose Pty Ltd." 可以使用对pdf进行修改的方法把水印去掉。

2.java实现对pdf文件的修改

引用的maven坐标

<!--修改pdf水印/分割pdf文件--><dependencies><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

整理的代码片段

package tvap.pdfutil;import com.itextpdf.text.BaseColor;import com.itextpdf.text.Font;import com.itextpdf.text.Rectangle;import com.itextpdf.text.pdf.BaseFont;import com.itextpdf.text.pdf.PdfContentByte;import com.itextpdf.text.pdf.PdfReader;import com.itextpdf.text.pdf.PdfStamper;import com.itextpdf.text.pdf.parser.PdfReaderContentParser;import tvap.pdfutil.listen_pdf.KeyWordPositionListener;import tvap.pdfutil.listen_pdf.MatchItem;import tvap.pdfutil.util.DateUtil;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/*** @author liyuliang* @date /7/14* pdf替换文字工具类* <p>* 思路:* 1.逐页搜索关键字,逐页匹配* 2.先读取一页的所有字符信息,存放到allItems中* 3.把一页的字符拼接成字符串,然后匹配关键字,匹配上,记录匹配的第一个字符的MatchItem信息;匹配不是,继续下一页匹配* 4.根据匹配字符串的长度和字符的宽高信息画遮罩层,然后替换文字生成新的pdf文件* <p>* 不足之处:* 1.目前只支持单字符串匹配* 2.替换之后的文字无法和原pdf中替换掉的文字信息一致(主要有:字体大小、样式等)* 3.某些情况下(主要是替换字体的大小)替换之后显示不是太整齐* 4.字体大小、样式无法把控* 5.无法匹配目标文字在两页中显示的情况(例如:目标文字:替换工具,第一页页尾有替换两字,第二页页首有工具二字)*/*/public class PdfDelwaterUtil {public static void main(String[] args) throws Exception {String src = "D:\\opt\\jenkins\\ilovepdf-opt2.pdf";String dest = "D:\\opt\\jenkins\\ilovepdf-no-water.pdf";String keyWord = "Evaluation Only. Created with Aspose.PDF. Copyright 2002- Aspose Pty Ltd.";String keyWordNew = "";System.out.println( DateUtil.getCurrentTime());pdfReplace(src, dest, keyWord, keyWordNew);System.out.println( DateUtil.getCurrentTime());}/*** 根据关键字和pdf路径,全文搜索关键字** @param filePath pdf目标路径* @param keyword 关键字* @return* @throws Exception*/public static List<MatchItem> matchAll(String filePath, String keyword) throws Exception {List<MatchItem> items = new ArrayList<MatchItem>();PdfReader reader = new PdfReader(filePath);//获取pdf页数int pageSize = reader.getNumberOfPages();//逐页匹配关键字for (int page = 1; page <= pageSize; page++) {items.addAll(matchPage(reader, page, keyword));}return items;}/*** 根据关键字、文档路径、pdf页数寻找特定的文件内容** @param reader* @param pageNumber 页数* @param keyword 关键字* @return* @throws Exception*/public static List<MatchItem> matchPage(PdfReader reader, Integer pageNumber, String keyword) throws Exception {PdfReaderContentParser parse = new PdfReaderContentParser(reader);Rectangle rectangle = reader.getPageSize(pageNumber);//匹配监听KeyWordPositionListener renderListener = new KeyWordPositionListener();renderListener.setKeyword(keyword);renderListener.setPageNumber(pageNumber);renderListener.setCurPageSize(rectangle);parse.processContent(pageNumber, renderListener);return findKeywordItems(renderListener, keyword);}/*** 找到匹配的关键词块** @param renderListener* @param keyword* @return*/public static List<MatchItem> findKeywordItems(KeyWordPositionListener renderListener, String keyword) {//先判断本页中是否存在关键词List<MatchItem> allItems = renderListener.getAllItems();//所有块LISTStringBuffer sbtemp = new StringBuffer("");for (MatchItem item : allItems) {//将一页中所有的块内容连接起来组成一个字符串。sbtemp.append(item.getContent());}List<MatchItem> matches = renderListener.getMatches();//一页组成的字符串没有关键词,直接return//第一种情况:关键词与块内容完全匹配的项,直接返回if (sbtemp.toString().indexOf(keyword) == -1 || matches.size() > 0) {return matches;}//第二种情况:多个块内容拼成一个关键词,则一个一个来匹配,组装成一个关键词sbtemp = new StringBuffer("");List<MatchItem> tempItems = new ArrayList();for (MatchItem item : allItems) {if (keyword.indexOf(item.getContent()) != -1) {tempItems.add(item);sbtemp.append(item.getContent());if (keyword.indexOf(sbtemp.toString()) == -1) {//如果暂存的字符串和关键词 不再匹配时sbtemp = new StringBuffer(item.getContent());tempItems.clear();tempItems.add(item);}if (sbtemp.toString().equalsIgnoreCase(keyword)) {//暂存的字符串正好匹配到关键词时matches.add(tempItems.get(0));//得到匹配的项sbtemp = new StringBuffer("");//清空暂存的字符串tempItems.clear();//清空暂存的LISTcontinue;//继续查找}} else {//如果找不到则清空sbtemp = new StringBuffer("");tempItems.clear();}}return matches;}/*** 替换目标文字,生成新的pdf文件** @param src 目标pdf路径* @param dest 新pdf的路径* @throws Exception*/public static void manipulatePdf(String src, String dest, List<MatchItem> matchItems, String keyWord, String keyWordNew) throws Exception {PdfReader reader = new PdfReader(src);PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));PdfContentByte canvas = null;Map<Integer, List<MatchItem>> mapItem = new HashMap<Integer, List<MatchItem>>();List<MatchItem> itemList = null;for (MatchItem item : matchItems) {Integer pageNum = item.getPageNum();if (mapItem.containsKey(pageNum)) {itemList = mapItem.get(pageNum);itemList.add(item);mapItem.put(pageNum, itemList);} else {itemList = new ArrayList<MatchItem>();itemList.add(item);mapItem.put(pageNum, itemList);}}//遍历每一页去修改for (Integer page : mapItem.keySet()) {List<MatchItem> items = mapItem.get(page);//遍历每一页中的匹配项for (MatchItem item : items) {canvas = stamper.getOverContent(page);float x = item.getX();float y = item.getY();float fontWidth = item.getFontWidth();float fontHeight = item.getFontHeight();canvas.saveState();canvas.setColorFill(BaseColor.WHITE);canvas.rectangle(x, y, fontWidth * keyWord.length(), fontWidth + 2);canvas.fill();canvas.restoreState();//开始写入文本canvas.beginText();BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);Font font = new Font(bf, fontWidth, Font.BOLD);//设置字体和大小canvas.setFontAndSize(font.getBaseFont(), fontWidth);//设置字体的输出位置canvas.setTextMatrix(x, y + fontWidth / 10 + 0.5f);//要输出的textcanvas.showText(keyWordNew);canvas.endText();}}stamper.close();reader.close();System.out.println("complete");}/*** 替换pdf中指定文字** @param src 目标pdf路径* @param dest 新pdf的路径* @param keyWord 替换的文字* @param keyWordNew 替换后的文字* @throws Exception*/public static void pdfReplace(String src, String dest, String keyWord, String keyWordNew) throws Exception {manipulatePdf(src, dest, matchAll(src, keyWord), keyWord, keyWordNew);}}

这个水印修改代码片段中还有,两个附属类如下:

实体类MatchItem

package com.Stream.pdfcut;/*** @author liyuliang* @date /7/14* 用来保存关键字信息*/public class MatchItem {//页数private Integer pageNum;//x坐标private Float x;//y坐标private Float y;//页宽private Float pageWidth;//页高private Float pageHeight;//匹配字符private String content;//字体宽private float fontWidth;//字体高private float fontHeight = 12;public Integer getPageNum() {return pageNum;}public void setPageNum(Integer pageNum) {this.pageNum = pageNum;}public Float getX() {return x;}public void setX(Float x) {this.x = x;}public Float getY() {return y;}public void setY(Float y) {this.y = y;}public Float getPageWidth() {return pageWidth;}public void setPageWidth(Float pageWidth) {this.pageWidth = pageWidth;}public Float getPageHeight() {return pageHeight;}public void setPageHeight(Float pageHeight) {this.pageHeight = pageHeight;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public float getFontWidth() {return fontWidth;}public void setFontWidth(float fontWidth) {this.fontWidth = fontWidth;}public float getFontHeight() {return fontHeight;}public void setFontHeight(float fontHeight) {this.fontHeight = fontHeight;}@Overridepublic String toString() {return "MatchItem{" +"pageNum=" + pageNum +", x=" + x +", y=" + y +", pageWidth=" + pageWidth +", pageHeight=" + pageHeight +", content='" + content + '\'' +'}';}}

和这个监听类KeyWordPositionListener

package tvap.pdfutil.listen_pdf;import com.itextpdf.awt.geom.Rectangle2D;import com.itextpdf.text.Rectangle;import com.itextpdf.text.pdf.parser.ImageRenderInfo;import com.itextpdf.text.pdf.parser.RenderListener;import com.itextpdf.text.pdf.parser.TextRenderInfo;import java.util.ArrayList;import java.util.List;/*** @author liyuliang* @date /7/14*//*** 用来匹配pdf的关键词 监听类*/public class KeyWordPositionListener implements RenderListener {//存放匹配上的字符信息private List<MatchItem> matches = new ArrayList<MatchItem>();//存放所有的字符信息private List<MatchItem> allItems = new ArrayList<MatchItem>();private Rectangle curPageSize;/*** 匹配的关键字*/private String keyword;/*** 匹配的当前页*/private Integer pageNumber;@Overridepublic void beginTextBlock() {//do nothing}@Overridepublic void renderText(TextRenderInfo renderInfo) {//获取字符String content = renderInfo.getText();Rectangle2D.Float textRectangle = renderInfo.getDescentLine().getBoundingRectange();MatchItem item = new MatchItem();item.setContent(content);item.setPageNum(pageNumber);item.setFontHeight(textRectangle.height == 0 ? 12 : textRectangle.height);//默认12item.setFontWidth(textRectangle.width);item.setPageHeight(curPageSize.getHeight());item.setPageWidth(curPageSize.getWidth());item.setX((float) textRectangle.getX());item.setY((float) textRectangle.getY());//若keyword是单个字符,匹配上的情况if (content.equalsIgnoreCase(keyword)) {matches.add(item);}//保存所有的项allItems.add(item);}@Overridepublic void endTextBlock() {//do nothing}@Overridepublic void renderImage(ImageRenderInfo renderInfo) {//do nothing}/*** 设置需要匹配的当前页** @param pageNumber*/public void setPageNumber(Integer pageNumber) {this.pageNumber = pageNumber;}/*** 设置需要匹配的关键字,忽略大小写** @param keyword*/public void setKeyword(String keyword) {this.keyword = keyword;}/*** 返回匹配的结果列表** @return*/public List<MatchItem> getMatches() {return matches;}public void setCurPageSize(Rectangle rect) {this.curPageSize = rect;}public List<MatchItem> getAllItems() {return allItems;}public void setAllItems(List<MatchItem> allItems) {this.allItems = allItems;}}

3.java实现对pdf文件的拆分

引入的maven坐标

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

代码片段

package tvap.pdfutil;import com.itextpdf.text.Document;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.PdfCopy;import com.itextpdf.text.pdf.PdfImportedPage;import com.itextpdf.text.pdf.PdfReader;import tvap.pdfutil.util.DateUtil;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;/*** 分割pdf文件工具类* @author liyuliang* @date /7/14*/public class PdfSpiltUtil {public static void main(String[] args) {String inputFile = "D:\\opt\\jenkins\\ilovepdf.pdfutil";System.out.println(DateUtil.getCurrentTime());try {splitFileBySiz(inputFile,10);} catch (Exception e) {e.printStackTrace();}System.out.println(DateUtil.getCurrentTime());}/*** 分割pdf文件,并设置尺寸* @param pdfFilePath* @param size* @throws Exception*/public static void splitFileBySiz (String pdfFilePath,int size)throws Exception{PdfReader reader = new PdfReader(pdfFilePath);int pagecount = reader.getNumberOfPages();for (int i = 0; i < pagecount / size + 1; i++) {if (i != pagecount / size) {splitFile(pdfFilePath, i * size + 1, (i + 1) * size,i);} else {splitFile(pdfFilePath, i * size + 1, pagecount,i);}}}/*** 分割pdf文件* @param pdfFile* @param from* @param end* @return*/public static String splitFile(String pdfFile, Integer from, Integer end,Integer i) {Document document = null;PdfCopy copy = null;try {PdfReader reader = new PdfReader(pdfFile);int n = reader.getNumberOfPages();if (end == 0) {end = n;}List<String> savepaths = new ArrayList<String>();int a = pdfFile.lastIndexOf(".pdfutil");String staticpath = pdfFile.substring(0, a);// String savepath = staticpath + "_from_" + from + "_to_" + end + "_.pdfutil";String savepath = staticpath + "_"+i+".pdfutil";savepaths.add(savepath);document = new Document(reader.getPageSize(1));copy = new PdfCopy(document, new FileOutputStream(savepaths.get(0)));document.open();for (int j = from; j <= end; j++) {document.newPage();PdfImportedPage page = copy.getImportedPage(reader, j);copy.addPage(page);}document.close();return new File(savepath).getName();} catch (IOException e) {return null;} catch (DocumentException e) {return null;}}}

4.java实现对pdf文件的水印添加

引入的maven坐标

<!--添加水印--><dependency><groupId>org.eclipse.birt.runtime.3_7_1</groupId><artifactId>com.lowagie.text</artifactId><version>2.1.7</version></dependency>

代码片段

package tvap.pdfutil;import java.awt.*;import java.io.FileOutputStream;import com.lowagie.text.Element;import com.lowagie.text.pdf.BaseFont;import com.lowagie.text.pdf.PdfContentByte;import com.lowagie.text.pdf.PdfGState;import com.lowagie.text.pdf.PdfReader;import com.lowagie.text.pdf.PdfStamper;import javax.swing.*;/*** 添加水印* @author liyuliang* @date /7/14*/public class PdfAddwaterUtil {public static void main(String[] args) {String inputFile = "D:\\opt\\jenkins\\ilovepdf-no-water.pdf";String outputFile = "D:\\opt\\jenkins\\ilovepdf_shuiyin.pdf";waterMark(inputFile,outputFile,"北京XXXX科技有限公司 专用");}public static void waterMark(String inputFile, String outputFile, String waterMarkName) {try {PdfReader reader = new PdfReader(inputFile);PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);Rectangle pageRect = null;PdfGState gs = new PdfGState();gs.setFillOpacity(0.3f);gs.setStrokeOpacity(0.4f);int total = reader.getNumberOfPages() + 1;JLabel label = new JLabel();FontMetrics metrics;int textH = 0;int textW = 0;label.setText(waterMarkName);metrics = label.getFontMetrics(label.getFont());textH = metrics.getHeight();textW = metrics.stringWidth(label.getText());PdfContentByte under;for (int i = 1; i < total; i++) {under = stamper.getOverContent(i);// 在内容上方加水印//content = stamper.getUnderContent(i);//在内容下方加水印gs.setFillOpacity(0.2f);// content.setGState(gs);under.beginText();under.setFontAndSize(base, 50);under.setTextMatrix(70, 200);under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, 300, 350, 55);under.endText();}//一定不要忘记关闭流stamper.close();reader.close();} catch (Exception e) {e.printStackTrace();}}}

以上是本人整理的4个对pdf文件操作的代码,看了很多文档感觉不容易,所以分享出来希望对需要的人有用,另外还有一个插件也是操作pdf的叫做 spire.pdf ,它的官网有使用文档有兴趣可以去看看,以上资源整理自网络。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。