C# 使用iTextSharp从PDF中删除Javascript

C# 使用iTextSharp从PDF中删除Javascript,c#,pdf,itextsharp,C#,Pdf,Itextsharp,这似乎是应该迅速完成的事情,但在实践中似乎存在一个问题。我有一堆PDF表单,其中包括表单字段和嵌入式javascript。我希望安全地删除javascript代码,但保留PDF表单字段不变 到目前为止,我已经找到了很多解决方案,但是所有的解决方案要么都删除了javascript和表单字段,要么都保持不变 这里有一个解决方案;它同时复制表单字段和javascript: var pdfReader = new PdfReader(infilename); using (MemoryStream me

这似乎是应该迅速完成的事情,但在实践中似乎存在一个问题。我有一堆PDF表单,其中包括表单字段和嵌入式javascript。我希望安全地删除javascript代码,但保留PDF表单字段不变

到目前为止,我已经找到了很多解决方案,但是所有的解决方案要么都删除了javascript和表单字段,要么都保持不变

这里有一个解决方案;它同时复制表单字段和javascript:

var pdfReader = new PdfReader(infilename);
using (MemoryStream memoryStream = new MemoryStream()) {
    PdfCopyFields copy = new PdfCopyFields(memoryStream);
    copy.AddDocument(pdfReader);
    copy.Close();
    File.WriteAllBytes(rawfilename, memoryStream.ToArray());
}
Document document = new Document();
using (MemoryStream memoryStream = new MemoryStream()) {
    PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
    document.Open();
    document.AddDocListener(writer);
    for (int p = 1; p <= pdfReader.NumberOfPages; p++) {
        document.SetPageSize(pdfReader.GetPageSize(p));
        document.NewPage();
        PdfContentByte cb = writer.DirectContent;
        PdfImportedPage pageImport = writer.GetImportedPage(pdfReader, p);
        int rot = pdfReader.GetPageRotation(p);
        if (rot == 90 || rot == 270) {
            cb.AddTemplate(pageImport, 0, -1.0F, 1.0F, 0, 0, pdfReader.GetPageSizeWithRotation(p).Height);
        } else {
            cb.AddTemplate(pageImport, 1.0F, 0, 0, 1.0F, 0, 0);
        }
    }
    document.Close();
    File.WriteAllBytes(rawfile, memoryStream.ToArray());
}
或者,我有解决方案B,它去掉了表单字段和javascript:

var pdfReader = new PdfReader(infilename);
using (MemoryStream memoryStream = new MemoryStream()) {
    PdfCopyFields copy = new PdfCopyFields(memoryStream);
    copy.AddDocument(pdfReader);
    copy.Close();
    File.WriteAllBytes(rawfilename, memoryStream.ToArray());
}
Document document = new Document();
using (MemoryStream memoryStream = new MemoryStream()) {
    PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
    document.Open();
    document.AddDocListener(writer);
    for (int p = 1; p <= pdfReader.NumberOfPages; p++) {
        document.SetPageSize(pdfReader.GetPageSize(p));
        document.NewPage();
        PdfContentByte cb = writer.DirectContent;
        PdfImportedPage pageImport = writer.GetImportedPage(pdfReader, p);
        int rot = pdfReader.GetPageRotation(p);
        if (rot == 90 || rot == 270) {
            cb.AddTemplate(pageImport, 0, -1.0F, 1.0F, 0, 0, pdfReader.GetPageSizeWithRotation(p).Height);
        } else {
            cb.AddTemplate(pageImport, 1.0F, 0, 0, 1.0F, 0, 0);
        }
    }
    document.Close();
    File.WriteAllBytes(rawfile, memoryStream.ToArray());
}
Document Document=新文档();
使用(MemoryStream MemoryStream=new MemoryStream()){
PdfWriter writer=PdfWriter.GetInstance(文档,内存流);
document.Open();
document.AddDocListener(编写器);

for(int p=1;p在for循环后添加以下行以保留AcroForm:

var form = pdfReader.AcroForm;
if (form != null)
   writer.CopyAcroForm(reader);

要操作单个PDF,您应该使用类
PdfStamper
并操作其内容,在您的示例中,迭代现有表单字段并删除JavaScript条目

与的第13章相对应的iTextSharp示例显示了如何将JavaScript操作添加到字段中,中心代码是:

PdfStamper stamper = new PdfStamper(reader, ms);

AcroFields form = stamper.AcroFields;
AcroFields.Item fd = form.GetFieldItem("married");

PdfDictionary dictYes = (PdfDictionary) PdfReader.GetPdfObject(fd.GetWidgetRef(0));
PdfDictionary yesAction = ...;
dictYes.Put(PdfName.AA, yesAction);
因此,要删除此类JavaScript表单字段操作,您必须迭代所有这些PDF表单字段,并删除关联字典中的/AA值:

dictXXX.Remove(PdfName.AA);
编辑:(由Ted Spence提供)以下是成功删除javascript的最终代码,同时保留所有表单字段不变:

using (MemoryStream memoryStream = new MemoryStream())
{
    PdfStamper stamper = new PdfStamper(pdfReader, memoryStream);
    for (int i = 0; i <= pdfReader.XrefSize; i++)
    {
        PdfDictionary pd = pdfReader.GetPdfObject(i) as PdfDictionary;
        if (pd != null)
        {
            pd.Remove(PdfName.AA); // Removes automatic execution objects
            pd.Remove(PdfName.JS); // Removes javascript objects
            pd.Remove(PdfName.JAVASCRIPT); // Removes other javascript objects
        }
    }
    stamper.Close();
    pdfReader.Close();
    File.WriteAllBytes(rawfile, memoryStream.ToArray());
}
使用(MemoryStream MemoryStream=new MemoryStream())
{
PdfStamper压模=新的PdfStamper(pdfReader、memoryStream);

对于(int i=0;i)函数“CopyAcroForm(reader)”在我的iTextSharp中似乎不存在-我本周下载了最新版本。这可能是扩展库中的函数吗?编辑-你可能会想到
PdfCopy.CopyAcroForm
。我会检查一下。坏消息-使用
PdfCopy.CopyAcroForm
不起作用。它复制了所有的javascript。谢谢!让我给你这是一个尝试,看看它是怎么做的。成功!这就成功了。让我修改你的答案,以准确地输入最终代码的阅读方式。@TedSpence当我看到你的编辑建议时,它已经被拒绝,因为它不正确,或者试图回复或评论现有的帖子。我将它包括在这里,但必须补充一点,你的解决方案太成功了,因为我t涉及每一个间接字典对象。另一方面,它忽略了内联字典。关于PDF规范,肯定有很多东西需要学习。我想创建一个更健壮的解决方案,所以如果有改进的方法,我希望看到它们。