以编程方式合并PDF,同时保持“组合文件...”书签结构?

时间:2011-04-01 13:38:56

标签: c# pdf vba batch-file excel-vba

我最初在Adobe的论坛上问这个问题,但还没有收到任何回复。

我必须每周将一组多个(100多个)PDF文件合并到一个报告中,到目前为止,我一直在手动选择文件,右键单击并选择“合并” Acrobat中支持的文件“。我想要做的是以编程方式复制这个完全相同的过程(最好是在Excel / VBA中,但C#或Batch命令是可接受的替代方案)。我目前有代码将组合pdf文件,但它不会保持书签结构与“在Acrobat中组合支持的文件”相同的方式。

换句话说,我有三个名为“A.pdf”,“B.pdf”和“C.pdf”的文件,每个文件包含两个名为“Bkmrk 1”和“Bkmrk 2”的书签。我想以编程方式将这三个文件组合成一个文件,该文件有9个书签,看起来像下面的结构:

A
    Bkmrk 1
    Bkmrk 2
B
    Bkmrk 1
    Bkmrk 2
C
    Bkmrk 1
    Bkmrk 2

我首先尝试通过Acrobat SDK自动执行该过程,但据我所知,Acrobat SDK不允许程序与执行“组合文件”菜单选项时出现的对话框进行交互,因此没有工作。我还尝试了以编程方式将页面从一个pdf文件插入到另一个文件中的选项,但这不会产生我正在寻找的书签结构,也不会让我操纵书签层次结构来创建我正在寻找的书签结构。 / p>

有没有人知道如何做到这一点?任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:2)

这对于工作来说是纯粹的地狱,所以我很乐意分享我所拥有的东西。这是根据我找到的here代码改编的,并将合并文件,并在每个合并点放置书签:

Private mlngBkmkCounter     As Long

Public Sub updfConcatenate(pvarFromPaths As Variant, _
                           pstrToPath As String)

    Dim origPdfDoc      As Acrobat.CAcroPDDoc
    Dim newPdfDoc       As Acrobat.CAcroPDDoc
    Dim lngNewPageCount As Long
    Dim lngInsertPage   As Long
    Dim i               As Long

    Set origPdfDoc = CreateObject("AcroExch.PDDoc")
    Set newPdfDoc = CreateObject("AcroExch.PDDoc")
    mlngBkmkCounter = 0

    'set the first file in the array as the "new"'
    If newPdfDoc.Open(pvarFromPaths(LBound(pvarFromPaths))) = True Then
        updfInsertBookmark "Test Start", lngInsertPage, , newPdfDoc
        mlngBkmkCounter = 1

        For i = LBound(pvarFromPaths) + 1 To UBound(pvarFromPaths)
            Application.StatusBar = "Merging " & pvarFromPaths(i) & "..."
            If origPdfDoc.Open(pvarFromPaths(i)) = True Then
                lngInsertPage = newPdfDoc.GetNumPages
                newPdfDoc.InsertPages lngInsertPage - 1, origPdfDoc, 0, origPdfDoc.GetNumPages, False
                updfInsertBookmark "Test " & i, lngInsertPage, , newPdfDoc
                origPdfDoc.Close
                mlngBkmkCounter = mlngBkmkCounter + 1
            End If
        Next i
        newPdfDoc.Save PDSaveFull, pstrToPath
    End If

ExitHere:
    Set origPdfDoc = Nothing
    Set newPdfDoc = Nothing
    Application.StatusBar = False
    Exit Sub

End Sub

插入书签代码......您需要对每个文档中的书签进行排列,然后设置它们

Public Sub updfInsertBookmark(pstrCaption As String, _
                              plngPage As Long, _
                     Optional pstrPath As String, _
                     Optional pMyPDDoc As Acrobat.CAcroPDDoc, _
                     Optional plngIndex As Long = -1, _
                     Optional plngParentIndex As Long = -1)

    Dim MyPDDoc         As Acrobat.CAcroPDDoc
    Dim jso             As Object
    Dim BMR             As Object
    Dim arrParents      As Variant
    Dim bkmChildsParent As Object
    Dim bleContinue     As Boolean
    Dim bleSave         As Boolean
    Dim lngIndex        As Long

    If pMyPDDoc Is Nothing Then
        Set MyPDDoc = CreateObject("AcroExch.PDDoc")
        bleContinue = MyPDDoc.Open(pstrPath)
        bleSave = True
    Else
        Set MyPDDoc = pMyPDDoc
        bleContinue = True
    End If

    If plngIndex > -1 Then
        lngIndex = plngIndex
    Else
        lngIndex = mlngBkmkCounter
    End If

    If bleContinue = True Then
        Set jso = MyPDDoc.GetJSObject
        Set BMR = jso.bookmarkRoot

        If plngParentIndex > -1 Then
            arrParents = jso.bookmarkRoot.Children
            Set bkmChildsParent = arrParents(plngParentIndex)
            bkmChildsParent.createchild pstrCaption, "this.pageNum= " & plngPage, lngIndex

        Else
            BMR.createchild pstrCaption, "this.pageNum= " & plngPage, lngIndex
        End If

        MyPDDoc.SetPageMode 3 '3 — display using bookmarks'

        If bleSave = True Then
            MyPDDoc.Save PDSaveIncremental, pstrPath
            MyPDDoc.Close
         End If
    End If

ExitHere:
    Set jso = Nothing
    Set BMR = Nothing
    Set arrParents = Nothing
    Set bkmChildsParent = Nothing
    Set MyPDDoc = Nothing
End Sub

使用:

Public Sub uTest_pdfConcatenate()

    Const cPath As String = "C:\MyPath\"

    updfConcatenate Array(cPath & "Test1.pdf", _
                          cPath & "Test2.pdf", _
                          cPath & "Test3.pdf"), "C:\Temp\TestOut.pdf"
End Sub

答案 1 :(得分:1)

您可能需要考虑使用Aspose.Pdf.Kit之类的商业工具来获得您所追求的灵活性。它支持文件串联和书签操作。

这是一个30天的无限期试用,所以如果它不适合你,你就不会真的输掉它。

答案 2 :(得分:1)

使用iText#(http://www.itextpdf.com/)。 imho它是最好的PDF工具之一。可以在此处找到(大约)您想要的代码http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html 不要担心所有的例子都谈论Java,.NET中的类和函数是相同的

HTH

马里奥

答案 3 :(得分:1)

Docotic.Pdf library可以合并PDF文件,同时保持大纲(书签)结构。

没有什么特别的事情要做。您只需一个接一个地附加所有文档即可。

using (PdfDocument pdf = new PdfDocument())
{
    string[] filesToMerge = ...
    foreach (string file in filesToMerge)
        pdf.Append(file);

    pdf.Save("merged.pdf");
}

免责声明:我为图书馆的供应商Bit Miracle工作。

答案 4 :(得分:0)

Acrobat SDK 可以让您创建和阅读书签。请查看您的SDK API参考:

PDDocGetBookmarkRoot()

PDBookmark* (AddChild, AddNewChild, GetNext, GetPrev... lots of functions in there)

如果“合并文件”对话框没有为您提供所需的控件,请创建自己的对话框。