合并pdf列表并创建新书签(C#)

时间:2013-12-17 14:26:02

标签: c# itextsharp

该项目使用C#并使用iTextSharp。

我有一个带有标题(字符串)和文件内容(字节数组)的字典。我遍历这个字典并将所有文件合并在一起。我现在需要的是在每个文件的第一页开头添加书签,但我不应该在最终文档中添加任何新页面或文本。我尝试了不同的解决方案,但似乎都添加了目录页面,每页之前的新页面或页面开头的一些文本。

这些文件最初都没有书签。

我正在寻找一个看起来像这样的书签结构:

  • File1中
  • 文件2
  • SomeCategory
    • 文件3
    • FILE4

如果有人能指出我正确的方向,我将非常感激。

我合并文件的功能如下:

/// <summary>
/// Merge PDF files, and stamp certificates. This is a modified version of the example in the link below.
/// See: http://www.codeproject.com/Articles/28283/Simple-NET-PDF-Merger for more information.            
/// </summary>
/// <param name="sourceFiles">Files to be merged</param>
/// <returns>Byte array with the combined files.</returns>
public static byte[] MergeFiles(Dictionary<string, byte[]> sourceFiles)
    {
        var document = new Document();
        var output = new MemoryStream();

        try
        {
            // Initialize pdf writer
            var writer = PdfWriter.GetInstance(document, output);
            writer.PageEvent = new PdfPageEvents();

            // Open document to write
            document.Open();
            var content = writer.DirectContent;

            // Iterate through all pdf documents
            foreach (var sourceFile in sourceFiles)
            {
                // Create pdf reader
                var reader = new PdfReader(sourceFile.Value);
                var numberOfPages = reader.NumberOfPages;

                // Iterate through all pages
                for (var currentPageIndex = 1; currentPageIndex <=
                                   numberOfPages; currentPageIndex++)
                {
                    // Determine page size for the current page
                    document.SetPageSize(
                       reader.GetPageSizeWithRotation(currentPageIndex));

                    // Create page
                    document.NewPage();

                    var importedPage =
                      writer.GetImportedPage(reader, currentPageIndex);

                    // Determine page orientation
                    var pageOrientation = reader.GetPageRotation(currentPageIndex);
                    if ((pageOrientation == 90) || (pageOrientation == 270))
                    {
                        content.AddTemplate(importedPage, 0, -1f, 1f, 0, 0,
                           reader.GetPageSizeWithRotation(currentPageIndex).Height);
                    }
                    else
                    {
                        content.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
                    }
                    // Add stamp to certificates
                    if (sourceFile.Key.IsValidDocumentReference())
                        AddStamp(content, document, sourceFile.Key, currentPageIndex, numberOfPages);

                }
            }
        }
        catch (Exception exception)
        {
            throw new Exception("An unexpected exception occured during the merging process", exception);
        }
        finally
        {
            document.Close();
        }
        return output.GetBuffer();
    }

1 个答案:

答案 0 :(得分:3)

感谢Bruno Lowagie指出了我正确的方向,我能够解决我的问题。

这是我的解决方案:

public static byte[] MergeFilesAndAddBookmarks(Dictionary<PrintDocument, byte[]> sourceFiles)
    {
        using (var ms = new MemoryStream())
        {
            using (var document = new Document())
            {
                using (var copy = new PdfCopy(document, ms))
                {
                    //Order the files by chapternumber
                    var files = sourceFiles.GroupBy(f => f.Key.ChapterNumber);

                    document.Open();

                    var outlines = new List<Dictionary<string, object>>();

                    var pageIndex = 1; 

                    foreach (var chapterGroup in files)
                    {
                        var map = new Dictionary<string, object>();
                        outlines.Add(map);
                        map.Add("Title", chapterGroup.First().Key.ChapterName);
                        var kids = new List<Dictionary<string, object>>();
                        map.Add("Kids", kids);

                        foreach (var sourceFile in chapterGroup)
                        {
                            using (var reader = new PdfReader(sourceFile.Value))
                            {
                                // add the pages
                                var n = reader.NumberOfPages;

                                for (var page = 0; page < n;)
                                {
                                    if (page == 0)
                                    {
                                        var kid = new Dictionary<string, object>();
                                        kids.Add(kid);
                                        kid["Title"] = sourceFile.Key.Title;
                                        kid["Action"] = "GoTo";
                                        kid["Page"] = String.Format("{0} Fit", pageIndex);
                                    }
                                    copy.AddPage(copy.GetImportedPage(reader, ++page));
                                }

                                pageIndex += n;
                                reader.Close();
                            }
                        }
                    }

                    copy.Outlines = outlines;
                    document.Close();
                    copy.Close();
                    ms.Close();
                }
            }
            return ms.ToArray();
        }
    } 
}

public class PrintDocument
{
    public string Title { get; set; }
    public string ChapterName { get; set; }
    public int ChapterNumber { get; set; }
}