pdf压缩,去除水印

  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.压缩,商业用途请使用正版;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值