iTextSharp - 在合并 PDF 中使用 PDFAction.GotoLocalPage

2023-11-30

我编写了一些代码,将多个 PDF 合并为一个 PDF,然后从 MemoryStream 中显示该 PDF。这很好用。我需要做的是将目录添加到文件末尾,并提供指向每个 PDF 开头的链接。我计划使用 GotoLocalPage 操作来执行此操作,该操作具有页码选项,但它似乎不起作用。如果我将下面代码的操作更改为 PDFAction.FIRSTPAGE 等 Presset 操作之一,它就可以正常工作。这是否不起作用,因为我使用 PDFCopy 对象作为 GotoLocalPage 的 writer 参数?

Document mergedDoc = new Document();
MemoryStream ms = new MemoryStream();
PdfCopy copy = new PdfCopy(mergedDoc, ms);
mergedDoc.Open();

MemoryStream tocMS = new MemoryStream();
Document tocDoc = null;
PdfWriter tocWriter = null;

for (int i = 0; i < filesToMerge.Length; i++)
{
     string filename = filesToMerge[i];

     PdfReader reader = new PdfReader(filename);
     copy.AddDocument(reader);

     // Initialise TOC document based off first file
     if (i == 0)
     {
          tocDoc = new Document(reader.GetPageSizeWithRotation(1));
          tocWriter = PdfWriter.GetInstance(tocDoc, tocMS);
          tocDoc.Open();
     }

     // Create link for TOC, added random number of 3 for now
     Chunk link = new Chunk(filename);
     PdfAction action = PdfAction.GotoLocalPage(3, new PdfDestination(PdfDestination.FIT), copy);
     link.SetAction(action);
     tocDoc.Add(new Paragraph(link));
}

// Add TOC to end of merged PDF
tocDoc.Close();
PdfReader tocReader = new PdfReader(tocMS.ToArray());
copy.AddDocument(tocReader);

copy.Close();

displayPDF(ms.ToArray());

我想另一种选择是链接到命名元素(而不是页码),但我不知道如何在添加到合并文档之前将“不可见”元素添加到每个文件的开头?


我只需要两张通行证就可以了。在第一遍中,按原样进行合并,但还要记录它应链接到的文件名和页码。在第二遍中,使用PdfStamper这将使您能够访问ColumnText您可以使用一般抽象,例如Paragraph以下是展示这一点的示例:

由于我没有您的文档,因此下面的代码创建 10 个文档,每个文档的页数是随机的,仅用于测试目的。 (显然您不需要执行这部分操作。)它还会创建一个简单的字典,以假文件名作为键,将 PDF 中的原始字节作为值。您有一个真正的文件集合可供使用,但您应该能够调整该部分。

//Create a bunch of files, nothing special here
//files will be a dictionary of names and the raw PDF bytes
Dictionary<string, byte[]> Files = new Dictionary<string, byte[]>();
var r = new Random();
for (var i = 1; i <= 10; i++) {
    using (var ms = new MemoryStream()) {
        using (var doc = new Document()) {
            using (var writer = PdfWriter.GetInstance(doc, ms)) {
                doc.Open();

                //Create a random number of pages
                for (var j = 1; j <= r.Next(1, 5); j++) {
                    doc.NewPage();
                    doc.Add(new Paragraph(String.Format("Hello from document {0} page {1}", i, j)));
                }
                doc.Close();
            }
        }
        Files.Add("File " + i.ToString(), ms.ToArray());
    }
}

下一个块将合并 PDF。这与您的代码基本相同,只是我不是在这里编写目录,而是跟踪我将来想要编写的内容。我在哪里使用file.value你会使用你的完整文件路径和我正在使用的位置file.key你可以使用你的文件名来代替。

//Dictionary of file names (for display purposes) and their page numbers
var pages = new Dictionary<string, int>();

//PDFs start at page 1
var lastPageNumber = 1;

//Will hold the final merged PDF bytes
byte[] mergedBytes;

//Most everything else below is standard
using (var ms = new MemoryStream()) {
    using (var document = new Document()) {
        using (var writer = new PdfCopy(document, ms)) {
            document.Open();

            foreach (var file in Files) {

                //Add the current page at the previous page number
                pages.Add(file.Key, lastPageNumber);

                using (var reader = new PdfReader(file.Value)) {
                    writer.AddDocument(reader);

                    //Increment our current page index
                    lastPageNumber += reader.NumberOfPages;
                }
            }
        }
    }
    mergedBytes = ms.ToArray();
}

最后一个块实际上写入了目录。如果我们使用一个PdfStamper我们可以创建一个ColumnText这允许我们使用Paragraphs

//Will hold the final PDF
byte[] finalBytes;
using (var ms = new MemoryStream()) {
    using (var reader = new PdfReader(mergedBytes)) {
        using (var stamper = new PdfStamper(reader, ms)) {

            //The page number to insert our TOC into
            var tocPageNum = reader.NumberOfPages + 1;

            //Arbitrarily pick one page to use as the size of the PDF
            //Additional logic could be added or this could just be set to something like PageSize.LETTER
            var tocPageSize = reader.GetPageSize(1);

            //Arbitrary margin for the page
            var tocMargin = 20;

            //Create our new page
            stamper.InsertPage(tocPageNum, tocPageSize);

            //Create a ColumnText object so that we can use abstractions like Paragraph
            var ct = new ColumnText(stamper.GetOverContent(tocPageNum));

            //Set the working area
            ct.SetSimpleColumn(tocPageSize.GetLeft(tocMargin), tocPageSize.GetBottom(tocMargin), tocPageSize.GetRight(tocMargin), tocPageSize.GetTop(tocMargin));

            //Loop through each page
            foreach (var page in pages) {
                var link = new Chunk(page.Key);
                var action = PdfAction.GotoLocalPage(page.Value, new PdfDestination(PdfDestination.FIT), stamper.Writer);
                link.SetAction(action);
                ct.AddElement(new Paragraph(link));
            }

            ct.Go();
        }
    }
    finalBytes = ms.ToArray();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iTextSharp - 在合并 PDF 中使用 PDFAction.GotoLocalPage 的相关文章

  • 如何在启用嵌入时间戳和 LTV 的情况下签署 PDF?

    我正在尝试签署启用了时间戳和 LTV 的 pdf 以便它在 Adob e Reader 中显示如下 在英语中 这意味着 签名包含嵌入的时间戳 和 签名启用了 LTV 这是我正在使用的代码 PrivateKey pk get pk from
  • 在chrome中将pdf渲染为iframe

    我正在尝试将 pdf 托管在隐藏的 iframe 中 但在 Chrome 中呈现较小的问题时遇到问题 我必须刷新页面才能正确加载 JSfiddle 在这里https jsfiddle net 464xo40f https jsfiddle
  • 如何应用 .diff 文件

    我有一个 diff 类型文件 看起来像爆炸了 diff git a res User lua b res User lua index db8c2cc 4d2af0f 100644 a res User lua b res User lua
  • 将jsp表导出到excel、word、pdf

    任何人都可以建议我任何库 jar 文件 我可以使用它们将我的表导出到 excel pdf word 请告诉我是否有任何可以在 jsp 中创建报告的库 还应该提到的是 您只需输出 HTML 表格并将响应类型设置为即可将表格导出到 Excela
  • 使用 Spring MVC 返回 PDF 文件

    实际上 我有这个功能 我有一个框架 可以在其中设置 URL ip port birt preview report report rptdesign format pdf parameters 并且该框架呈现 PDF 文件 但我想隐藏该网址
  • PyFPDF在指定大小时无法添加页面

    在 pyfpdf 文档上据说可以在添加页面时指定格式 fpdf add page orientation format same False 但在指定格式时它给了我一个错误 error pdf add page format 1000 10
  • 设置 8 1/2" x 12" itext 页面尺寸 [重复]

    这个问题在这里已经有答案了 我正在使用 itext PDF 我需要将 PDF 文档大小设置为德国标准 Fanfold 8 1 2 x 12 我不知道如何在 Itext 文档中设置英寸 Now I can set paper size as
  • 将带有 itext 滚动条的表格的可编辑单元格设为只读

    请找到下面的代码 public class MakingFieldReadOnly implements PdfPCellEvent The resulting PDF public static final String RESULT1
  • Git 合并删除文件

    这是第二次发生这种情况 当我进行合并时 我后来意识到正在合并的分支中的一些文件不再位于正在合并的分支中 最新的例子是我们有一个功能分支 我一直在合并主开发分支中的更改 合并后我们丢失了很多文件 并且它们现在不存在于功能分支中 为什么会出现这
  • 在Python中读取PDF属性/元数据

    如何使用 Python 读取 PDF 文件中存储的属性 元数据 例如标题 作者 主题和关键字 Try pdfminer https github com euske pdfminer from pdfminer pdfparser impo
  • 飞碟 - html 实体未呈现

    我正在使用 Flying saucer lib 生成 pdf 但我对一些 html 实体有问题 我已经在寻找解决方案 我在这个论坛和其他地方找到了很多提示 但仍然存在问题 我尝试过这种方法 http sdtidbits blogspot c
  • Git:如何维护项目的两个分支并仅合并共享数据?

    假设我有一个项目的两个分支 IMClient MacOS 和 IMClient Windows 它们的代码仅 比方说 一个目录 main 有所不同 所有其他目录都包含与系统无关的代码并且可以互换 有些工作人员在 Windows 版本上工作
  • 如何在模态窗口中显示pdf? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个模式窗口 其中包含锚文本 当我单击此链接时 它必须调用其他位置的 pdf 并将其显示在弹出窗口中 我怎样才能做到这一点 请帮忙
  • 在 iOS 中,如何以编程方式填写 pdf 表单字段?

    我需要获取一个现有的 pdf 文件 并以编程方式填写带有文本的表单字段列表 然后保存 pdf 而不将其显示给用户 例如 如果 pdf 文件包含名为 LastName 和 FirstName 的字段 我想将 FirstName 的值设置为 L
  • 将固定文档/XPS 打印为 PDF,而不显示文件保存对话框

    我有一个FixedDocument我允许用户在 WPF GUI 中预览 然后打印到纸张上 而不显示任何 Windows 打印对话框 如下所示 private void Print PrintQueueCollection printQueu
  • Swift Siesta 访问响应原始数据

    我的 API 中有一个返回 PDF 文件内容的方法 如何在成功回调中获取响应的原始数据 所有午睡响应均以原始数据开始 以基础类型的形式Data 然后运行变压器管道 http bustoutsolutions github io siesta
  • 如何为 Android 创建我们自己的 PDF 查看器?

    我想构建一个可在我的 Android 应用程序中使用的 PDF 阅读器 查看器 但我无法使用 Google 文档来阅读我的内容 我无法使用我的设备中已安装的任何 PDF 阅读器 它应该位于我的应用程序内 并且不会通过互联网公开我的安全内容
  • 如何从纯文本文件中解析文本并使用结果突出显示 PDF 文件

    早在 2010 年 就有人声称能够做到这一点 http www mobileread com forums showthread php t 103847 http www mobileread com forums showthread
  • 如何根据查找表匹配多列

    我有以下两个数据框 lookup lt data frame id c A B C price c 1 2 3 results lt data frame price 1 c 2 2 1 price 2 c 3 1 1 我现在想要浏览所有列
  • 如何在Git中手动合并所有文件?

    我想合并所有文件manually有了 meld 或任何其他 diff 工具 我如何使用 Git 来做到这一点 当我跑步时git mergetool它说no files need merging 所以我想只有当我有冲突时我才能做到这一点 有更

随机推荐