替换PDF中的敏感信息

替换PDF中的敏感信息


FTP文档中有敏感信息不能显示给客户,之前我采用的是覆盖的方法,但后来发现,那不过是掩耳盗铃,通过覆盖的方法只是在文字表面加了一层遮羞布,一样可以通过搜索和copy获取到我们要加密的内容。
在上一篇博客中,我通过将pdf转为图片之后再转回pdf曲线救国的方式实现了业务需求。
但是今天有一个客户提出新的要求,对方要求pdf不能是图片的方式,因为对方还需要对pdf进行编辑,如果是图片的方式,对方无法进行二次修改。
于是有了这篇文章,
以下这段代码替换了原来的覆盖代码,我们直接将敏感信息替换为空字符。
这一路走来真不容易啊,感叹自己懂的东西还是太少了,一个业务需求愣是让我不断都优化改进,浪费那么多人力物力。我愧对祖国人民,愧对党对我的信任。

 /**
         * 替换敏感词
         */
        PDDocument doc = null;
        try {
            doc = PDDocument.load(srcFile);
            List pages = doc.getDocumentCatalog().getAllPages();
            for (int i = 0; i < pages.size(); i++) {
                PDPage page = (PDPage) pages.get(i);
                PDStream stream = page.getContents();
                PDFStreamParser streamParser = new PDFStreamParser(stream.getStream());
                streamParser.parse();
                List tokens = streamParser.getTokens();
                for (int k = 0; k < tokens.size(); k++) {
                    Object obj = tokens.get(k);
                    if (obj instanceof PDFOperator) {
                        //pdf操作器对象
                        PDFOperator op = (PDFOperator) obj;
                        if (Objects.equals(op.getOperation(), "Tj")) {
                            //COSString对象>>创建java字符串的一个新的文本字符串。
                            COSString previous = (COSString) tokens.get(k - 1);
                            //将此字符串的内容作为PDF文本字符串返回。
                            String val = previous.getString();
                            for (WordItem item : wordItems) {
                                if (Objects.equals(item.getContent(), val)) {
                                    Logs.info("内容匹配了");
                                    previous.reset();
                                    //设置字符编码格式
                                    previous.append("".getBytes("GBK"));
                                }
                            }
                        } else if (Objects.equals(op.getOperation(), "TJ")) {
                            //COSArray是pdfbase对象数组,作为PDF文档的一部分
                            COSArray previous = (COSArray) tokens.get(k - 1);
                            //循环previous
                            for (int j = 0; j < previous.size(); j++) {
                                //这将从数组中获取一个对象,这将取消引用该对象
                                //如果对象为cosnull,则返回null
                                Object arrElement = previous.getObject(j);
                                if (arrElement instanceof COSString) {
                                    //COSString对象>>创建java字符串的一个新的文本字符串。
                                    COSString cosString = (COSString) arrElement;
                                    //将此字符串的内容作为PDF文本字符串返回。
                                    String val = cosString.getString();
                                    for (WordItem item : wordItems) {
                                        if (Objects.equals(item.getContent(), val)) {
                                            Logs.info("内容匹配了");
                                            cosString.reset();
                                            //设置字符编码格式
                                            cosString.append("".getBytes("GBK"));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                //创建一个PDStream 流对象
                PDStream updatedStream = new PDStream(doc);
                //创建一个输出流接收updatedStream
                OutputStream out = updatedStream.createOutputStream();
                //将接受一个列表并写出它们的流。
                ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
                //写入一系列标记,后面跟着一行新行
                tokenWriter.writeTokens(tokens);
                //当前页设置新的内容
                page.setContents(updatedStream);
                //修改后保存的路径
                doc.save(newFile);
            }
 
        } catch (Exception e) {
            Logs.error(e.getMessage(), e);
        }

你可能感兴趣的:(java)