【问题标题】:Adding Text/Annotations into existing PDF file and View/Rendering the output in android在现有 PDF 文件中添加文本/注释并在 android 中查看/渲染输出
【发布时间】:2021-03-19 18:36:42
【问题描述】:

我正在开发 pdf 编辑器

我已经使用基于 iText 的 OpenPDF 核心对 pdf 文件进行了更改

我正在使用AndroidPdfViewer查看PDF文件

我的问题是:

  1. 将文本或标签或图标等新注释添加到现有 pdf 文件中。 已解决

  2. 在将注释添加到 pdf 文件后立即显示新的更改。(已解决)

  3. 将用户点击转换为 Pdf 文件坐标,以根据用户点击位置添加新注释。

  4. 在添加的注释上获取点击事件并读取添加到该注释中的元数据,例如:读取设置在图标注释上的标签哈希 id。已解决

  5. 从 PDF 文件中删除添加的注释。

任何帮助表示赞赏

更新

================================================ ==========================

方案一:添加注解

  • 这是我的代码 sn-p,用于将图标注释添加到现有 pdf 文件中。

public static void addWatermark(Context context, String filePath) throws FileNotFoundException, IOException {

        // get file and FileOutputStream
        if (filePath == null || filePath.isEmpty())
            throw new FileNotFoundException();

        File file = new File(filePath);

        if (!file.exists())
            throw new FileNotFoundException();

        try {

            // inout stream from file
            InputStream inputStream = new FileInputStream(file);

            // we create a reader for a certain document
            PdfReader reader = new PdfReader(inputStream);

            // get page file number count
            int pageNumbers = reader.getNumberOfPages();

            // we create a stamper that will copy the document to a new file
            PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(file));

            // adding content to each page
            int i = 0;
            PdfContentByte under;

            // get watermark icon
            Image img = Image.getInstance(PublicFunction.getByteFromDrawable(context, R.drawable.ic_chat));
            img.setAnnotation(new Annotation("tag", "gd871394bh2c3r", 0, 0, 0, 0));
            img.setAbsolutePosition(230, 190);
            img.scaleAbsolute(50, 50);

            while (i < pageNumbers) {
                i++;
                // watermark under the existing page
                under = stamp.getUnderContent(i);
                under.addImage(img);
            }

            // closing PdfStamper will generate the new PDF file
            stamp.close();

        } catch (Exception de) {
            de.printStackTrace();
        }

    }
}

解决方案 2:显示新更改

  • 这是我添加注释后刷新视图的代码 sn-p,我已将其添加到 AndroidPdfViewer 核心类中。
public void refresh(int currPage) {

            currentPage = currPage;

            if (!hasSize) {
                waitingDocumentConfigurator = this;
                return;
            }
            PDFView.this.recycle();
            PDFView.this.callbacks.setOnLoadComplete(onLoadCompleteListener);
            PDFView.this.callbacks.setOnError(onErrorListener);
            PDFView.this.callbacks.setOnDraw(onDrawListener);
            PDFView.this.callbacks.setOnDrawAll(onDrawAllListener);
            PDFView.this.callbacks.setOnPageChange(onPageChangeListener);
            PDFView.this.callbacks.setOnPageScroll(onPageScrollListener);
            PDFView.this.callbacks.setOnRender(onRenderListener);
            PDFView.this.callbacks.setOnTap(onTapListener);
            PDFView.this.callbacks.setOnLongPress(onLongPressListener);
            PDFView.this.callbacks.setOnPageError(onPageErrorListener);
            PDFView.this.callbacks.setLinkHandler(linkHandler);

            if (pageNumbers != null) {
                PDFView.this.load(documentSource, password, pageNumbers);
            } else {
                PDFView.this.load(documentSource, password);
            }
        }

解决方案 4:点击 pdf 中的对象

我已经创建注释并将其设置为添加的图像对象,AndroidPdfViewer 有一个事件处理程序,这里是示例

@Override
public void handleLinkEvent(LinkTapEvent event) {
        // do your stuff here
}

我将在我的问题中添加其他新的解决方案,作为更新部分。

【问题讨论】:

  • “这是我的代码 sn-p 用于将文本添加到 pdf 文件中,但这将替换为所有 Pdf 文件,而不仅仅是插入其中。” - 看例如使用 PdfReader / PdfStamper 对更改现有 PDF。
  • @mkl 感谢您的回复,您能否提供有关此问题的更多详细信息或参考资料?我使用 PdfReader 读取 pdf 内容,使用 PdfStamper 读取 Pdf 文件元数据。
  • “你能提供更多关于这个问题的细节或参考吗?” - 我刚刚写了一个答案,提供了这部分的一些细节。我不了解 Android PDF 查看器,因此无法回答您的这部分问题。
  • 是的,我已经使用PDFStamper 将我的更改附加到PDF 文件的基础中,现在我正在努力测试所有PdfViewers 以获取用户集成,例如文本选择或添加注释的点击事件.我将在我的问题中添加我的代码作为更新部分。

标签: android pdf itext androidpdfviewer openpdf


【解决方案1】:

这是我的代码 sn-p 用于将文本添加到 pdf 文件中,

您的代码不会将文本添加到现有 pdf 文件中。它创建一个 PDF,向其中添加文本,然后这个新PDF 附加到可能已经包含PDF 的现有文件中。结果是一个包含两个 PDF 的文件。

连接两个相同类型的文件很少会产生该类型的有效文件。这确实适用于某些文本格式(纯文本、csv、...),但几乎不适用于二进制格式,尤其是不适用于 PDF。

因此,您的查看器会显示一个作为 PDF 无效的文件,因此您的查看器可能只是显示错误并退出。但是 PDF 查看器因试图修复他们收到的文件而臭名昭著,每个查看器都以自己的方式修复。因此,根据查看器的不同,您还可以看到仅原始文件、仅新文件、两者的组合、空文件或其他修复结果。

所以你的观察,

但这将替换为所有 Pdf 文件,而不仅仅是插入其中

这不足为奇,但可能因观众而异。


要使用 OpenPDF(或 6 之前的任何 iText 版本或从此类版本派生的其他库)实际更改现有文件,您应该使用 PdfReader 阅读现有 PDF,在 PdfStamper 中操作该阅读器,然后关闭那个印章。

例如:

PdfReader reader = new PdfReader("original.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("original-stamped.pdf"));

PdfContentByte cb = stamper.getOverContent(1);
cb.beginText();
cb.setTextMatrix(100, 400);
cb.showText("Text at position 100,400.");
cb.endText();

stamper.close();
reader.close();

这里特别注意使用不同的文件名。关闭stamperreader后,可以删除原PDF,换成盖章版。

如果不希望有第二个文件,您也可以使用ByteArrayOutputStream 初始化PdfStamper,并在关闭stamperreader 后将原始文件的内容替换为ByteArrayOutputStream.

【讨论】:

  • 感谢您的帮助@mkl 我实际上已经解决了我的所有问题,除了最后一个问题,我正在锁定从 pdf 中删除这些项目的最佳方法。我已经在github 中为您提出了一个问题。你有什么想法吗?tnQ
  • 在接下来的两周里,我很可能只会在智能手机上出现堆栈溢出问题,这使得正确的答案变得困难。如果你之后仍然感兴趣,我会尝试写一些东西。
  • 是的@mkl 我真的对这个问题很感兴趣:) 谢谢你的帮助,如果你给我一些keywords 或任何links 很好,我会搜索并自己审核。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多