pdf压缩,去除水印 2023-09-27 10:52 283阅读 0赞 1. Aspose.pdf压缩pdf文件,去除 Evaluation Only. Created with Aspose.PDF. Copyright 2002-2022 Aspose Pty Ltd. 废话不多说;直接上代码; 2. pom Maven 引入 <!-- aspose-pdf --> <dependency> <groupId>com.luhuiguo</groupId> <artifactId>aspose-pdf</artifactId> <version>22.4</version> </dependency> <!--itextpdf 修改pdf水印/分割pdf文件--> <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> 3.aspose压缩核心工具类 package cn.hrfax.car.utils.pdf; import com.aspose.pdf.Document; /** * * ClassName: AsposePdfUtils * @Description:pdf 压缩工具类 * @author lh.l */ public class AsposePdfUtils { 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(); } public static void main(String[] args) { String source = "D:/data/pdf/source/1.pdf"; String target = "D:/data/pdf/target/1.pdf"; optimize(source, target); System.out.println("转换完成"); } } 4.itextpdf去除水印工具类 package cn.hrfax.car.utils.pdf; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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; /** * pdf 替换文字工具类 * <p> * 思路: * 1.逐页搜索关键字,逐页匹配 * 2.先读取一页的所有字符信息,存放到allItems中 * 3.把一页的字符拼接成字符串,然后匹配关键字,匹配上,记录匹配的第一个字符的MatchItem信息;匹配不是,继续下一页匹配 * 4.根据匹配字符串的长度和字符的宽高信息画遮罩层,然后替换文字生成新的pdf文件 * <p> * 不足之处: * 1.目前只支持单字符串匹配 * 2.替换之后的文字无法和原pdf中替换掉的文字信息一致(主要有:字体大小、样式等) * 3.某些情况下(主要是替换字体的大小)替换之后显示不是太整齐 * 4.字体大小、样式无法把控 * 5.无法匹配目标文字在两页中显示的情况(例如:目标文字:替换工具,第一页页尾有替换两字,第二页页首有工具二字) */ public class PdfDelwaterUtil { private static final String KEY_WORD = "Evaluation Only. Created with Aspose.PDF. Copyright 2002-2022 Aspose Pty Ltd."; private static final String KEY_WORD_NEW = ""; public static void main(String[] args) throws Exception { String source = "D:\\data\\pdf\\target\\1.pdf"; String target = "D:\\data\\pdf\\target\\new\\1.pdf"; System.out.println("开始"); pdfReplace(source, target, KEY_WORD, KEY_WORD_NEW); System.out.println("结束"); } /** * 根据关键字和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 List<MatchItem> allItems = renderListener.getAllItems(); StringBuffer 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(""); //清空暂存的LIST tempItems.clear(); //继续查找 continue; } } 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(); 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); //要输出的text canvas.showText(keyWordNew); canvas.endText(); } } stamper.close(); reader.close(); } /** * 替换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); } } 5.pdf的关键词 监听类 package cn.hrfax.car.utils.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; /** * 用来匹配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; @Override public void beginTextBlock() { //do nothing } @Override public 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);//默认12 item.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); } @Override public void endTextBlock() { //do nothing } @Override public 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; } } 6.保存关键字信息类 package cn.hrfax.car.utils.pdf; /** * 保存关键字信息 */ 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; } @Override public String toString() { return "MatchItem{" + "pageNum=" + pageNum + ", x=" + x + ", y=" + y + ", pageWidth=" + pageWidth + ", pageHeight=" + pageHeight + ", content='" + content + '\'' + '}'; } } 备注:asposePdf.压缩,商业用途请使用正版;
还没有评论,来说两句吧...