首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用iTextSharp从PDF中删除Javascript

使用iTextSharp从PDF中删除Javascript
EN

Stack Overflow用户
提问于 2013-05-07 00:16:59
回答 2查看 5K关注 0票数 2

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

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

下面是解决方案A;它同时复制表单字段和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());
}

或者,我有解决方案B,它去掉了表单字段和javascript:

代码语言:javascript
复制
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());
}

是否有人知道如何修改解决方案A或B以消除javascript,但保留表单字段的位置?

编辑:解决方案代码在这里!

代码语言:javascript
复制
using (MemoryStream memoryStream = new MemoryStream()) {
    PdfStamper stamper = new PdfStamper(pdfReader, memoryStream);
    for (int i = 0; i <= pdfReader.XrefSize; i++) {
        object o = pdfReader.GetPdfObject(i);
        PdfDictionary pd = o as PdfDictionary;
        if (pd != null) {
            pd.Remove(PdfName.AA);
            pd.Remove(PdfName.JS);
            pd.Remove(PdfName.JAVASCRIPT);
        }
    }
    stamper.Close();
    pdfReader.Close();
    File.WriteAllBytes(rawfile, memoryStream.ToArray());
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-07 08:45:38

要操作单个PDF,您应该使用类PdfStamper并操作它的内容,在您的情况下,迭代现有的表单字段并删除JavaScript条目。

iTextSharp示例AddJavaScriptToForm.cs对应于行动中的iText -第2版第13章中的AddJavaScriptToForm.java,它展示了JavaScript操作是如何将添加到字段中的,中心代码是:

代码语言: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值:

代码语言:javascript
复制
dictXXX.Remove(PdfName.AA);

编辑:(由Ted提供)这里是最终代码,它成功地删除了javascript,同时保留了所有表单字段:

代码语言: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());
}

编辑:(由mkl提供)上面的解决方案有些过分,因为它涉及到每个间接字典对象。另一方面,它忽略了内联字典(不过,我还没有检查规范;可能所有的/AA/JS/JAVASCRIPT条目都只出现在必须是间接对象的字典中,或者至少是被该代码取消引用的字典)。

如果完成这一任务是我的工作,我将尝试访问可能更具体地携带JavaScript的对象。

但是,这个过度实现的过程的优点可能是,即使检查PDF对象,这些对象目前没有被指定为带有JavaScript,但将在以后的PDF版本中进行检查。

票数 4
EN

Stack Overflow用户

发布于 2013-05-07 03:55:20

在for循环后添加以下行以保留AcroForm:

代码语言:javascript
复制
var form = pdfReader.AcroForm;
if (form != null)
   writer.CopyAcroForm(reader);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16409278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档