从MS-WORD生成的pdf中删除水印

时间:2016-10-05 09:45:39

标签: itext pdfbox watermark

我一直在寻找从 MS-WORD 生成的 PDF 中删除水印的解决方案, 我使用了以下link的解决方案,这适用于从Itext生成水印的文件pdf

2 个答案:

答案 0 :(得分:0)

这是适用于您的文件的Apache PDFBox解决方案。它很可能不适用于其他word文件,但值得一试。要了解我的操作,请使用PDFBox PDFDebugger命令行应用程序(或使用itext RUPS)打开旧文件和新文件,然后查看“内容”条目。

我删除的部分以

开头
/Artifact << /Attached [ /Top ] /Type /Pagination /Subtype /Header >> BDC

结束
EMC

然而,那个还包含颜色和字体设置,所以我保留了这些。在真实文件中,该段可能包含更多有用的数据(毕竟,它被命名为“Header”)和不同类型的颜色设置,因此需要更多的逻辑。

PDDocument document = PDDocument.load(new File("Saura.pdf"));
if (document.isEncrypted())
{
    System.err.println("Error: Encrypted documents are not supported for this example.");
    System.exit(1);
}
for (PDPage page : document.getPages())
{
    PDFStreamParser parser = new PDFStreamParser(page);
    parser.parse();
    List<Object> tokens = parser.getTokens();
    List<Object> newTokens = new ArrayList<Object>();
    List<Object> parameters = new ArrayList<Object>();
    boolean skip = false;
    // PDF content stream tokens have the forn
    // paramater1...parameterN operator
    for (Object token : tokens)
    {
        if (token instanceof Operator)
        {
            Operator op = (Operator) token;
            if ("BDC".equals(op.getName()))
            {
                // "Watermark" starts with
                // /Artifact << /Attached [ /Top ] /Type /Pagination /Subtype /Header >> BDC
                if (parameters.size() == 2 && COSName.ARTIFACT.equals(parameters.get(0)) && parameters.get(1) instanceof COSDictionary)
                {
                    COSDictionary dict = (COSDictionary) parameters.get(1);
                    if (COSName.getPDFName("Header").equals(dict.getItem(COSName.SUBTYPE)))
                    {
                        skip = true;
                    }
                }
            }
            if (!skip || "g".equals(op.getName()) || "G".equals(op.getName()) || "Tf".equals(op.getName()))
            {
                // even when skipping, don't remove color and font settings
                newTokens.addAll(parameters);
                newTokens.add(op);
            }
            if ("EMC".equals(op.getName()))
            {
                // "Watermark" ends with EMC
                skip = false;                            
            }
            parameters = new ArrayList<Object>();
        }
        else
        {
            parameters.add(token);
        }
    }
    PDStream newContents = new PDStream(document);
    OutputStream out = newContents.createOutputStream(COSName.FLATE_DECODE);
    ContentStreamWriter writer = new ContentStreamWriter(out);
    writer.writeTokens(newTokens);
    out.close();
    page.setContents(newContents);
}
document.save(new File("Saura2.pdf"));

答案 1 :(得分:0)

我刚刚在Kotlin中编写了一段代码来删除水印。 我对PDF一无所知,但希望对您有所帮助。

    @Test
    fun test() {
        val pdf = PDDocument.load(File("/tmp/original.pdf"))

        pdf.pages.forEachIndexed { index, p ->
            val tokens = ArrayList(PDFStreamParser(p).apply { parse() }.tokens)
            val found = tokens.indexOfLast {
                it is COSDictionary && it.toString().contains("Watermark")
            }
            if (found >= 0) {
                runCatching {
                    val start = (found downTo 0).first { i ->
                        tokens[i].let { it is Operator && it.name == "Q" }
                    }
                    val end = (found until tokens.size).first { i ->
                        tokens[i].let { it is Operator && it.name == "Q" }
                    }
                    //remove unwanted
                    tokens.subList(start, end).clear()

                    p.setContents(PDStream(pdf).apply {
                        createOutputStream(COSName.FLATE_DECODE).use {
                            ContentStreamWriter(it).writeTokens(tokens)
                        }
                    })
                }.onFailure {
                    //debug something.
                    println("err: $p, $index")
                    throw it
                }
            }
        }

        pdf.save(File("/tmp/output.pdf"))
    }