iTextSharp - 更改可选内容组的顺序

时间:2014-04-24 21:20:04

标签: c# pdf itextsharp

我有一个带有层次结构(也就是OCG)的PDF文件。使用以下代码段

var ocProps = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES);
var occd = ocProps.GetAsDict(PdfName.D);
var order = occd.GetAsArray(PdfName.ORDER);

我可以从源文件中查询当前订单。但我不知道如何修改此数据,以便将其复制到包含以下代码段的新文件中。

var reader = new PdfReader(input);
var document = new Document(reader.GetPageSizeWithRotation(1));
var pdfCopyProvider = new PdfCopy(document,
    new System.IO.FileStream(output, System.IO.FileMode.Create));            
document.Open();
// TBD do OCG modification ...
var importedPage = pdfCopyProvider.GetImportedPage(reader, 1);
pdfCopyProvider.AddPage(importedPage);
document.Close();

但是,默认情况下,ocg信息被复制到新的pdf文件中。几周前我看到Bruno Lowagie关于ocgs https://stackoverflow.com/questions/21573892/itextsharp-merge-impose-pdfs-while-maintaining-layers-optional-content-groups合并的评论,但我不确定这是否包括简单的复制。

欢迎提出任何暗示。合并ocgs可能是未来的主题,因此也欢迎关于该主题的提示

此致  霍尔格

补充:我使用的是最新版本5.5.0.0

添加了: 除了布鲁诺的答案,我发布了操纵PDF方法的C#版本

public void ManipulatePdf(string source, string destination)
    {
        var reader = new PdfReader(source);
        var ocProps = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES);
        var occd = ocProps.GetAsDict(PdfName.D);
        var order = occd.GetAsArray(PdfName.ORDER);

        var nestedLayers = (PdfObject)order[0];
        var nestedLayerArray = (PdfObject)order[1];
        var groupedLayers = (PdfObject)order[2];
        var radiogroup = (PdfObject)order[3];

        order[0] = radiogroup;
        order[1] = nestedLayers;
        order[2] = nestedLayerArray;
        order[3] = groupedLayers;

        var stamper = new PdfStamper(reader, new System.IO.FileStream(destination, System.IO.FileMode.Create));

        stamper.Close();
        reader.Close();
    }

1 个答案:

答案 0 :(得分:0)

您已经非常接近解决方案了。请参阅ChangeOCGOrder,了解如何将ocg.pdf更改为ocg_reordered.pdf。 (代码是用Java编写的,但你不应该把它移植到... VB.NET吗?)

你已经有过这样的事情:

PdfDictionary catalog = reader.getCatalog();
PdfDictionary ocProps = catalog.getAsDict(PdfName.OCPROPERTIES);
PdfDictionary occd = ocProps.getAsDict(PdfName.D);
PdfArray order = occd.getAsArray(PdfName.ORDER);

这很好:你正在寻找合适的地方!

现在你需要这样的东西:

PdfObject nestedLayers = order.getPdfObject(0);
PdfObject nestedLayerArray = order.getPdfObject(1);
PdfObject groupedLayers = order.getPdfObject(2);
PdfObject radiogroup = order.getPdfObject(3);
order.set(0, radiogroup);
order.set(1, nestedLayers);
order.set(2, nestedLayerArray);
order.set(3, groupedLayers);

在我的示例中,ORDER数组包含4个元素。我得到了这四个元素,并且我改变了原始数组中条目的顺序。

请注意,我也可以这样做:

order.addFirst(order.remove(3));

这与上面的8行代码具有相同的效果,但是8行有助于您理解该机制。