【问题标题】:Add links to PDF programmatically以编程方式添加指向 PDF 的链接
【发布时间】:2014-04-11 22:02:30
【问题描述】:

我有大约 180 个从地理数据库生成的 PDF 文件。我想根据需要以编程方式在顶部、底部、左侧和右侧添加链接作为热点(无文本),以导航到相邻的页面文件。我还想在页面左下角的 3x3 网格上添加链接以进行额外导航。网格已经在现有的 PDF 中,只是没有链接。每个页面总共可能添加 14 个链接

我愿意接受有关如何解决此问题的建议。我正在使用 Acrobat Pro XI,我熟悉各种编程语言 python、vb.net、C#...只是没有直接处理 PDF 文件的经验。

【问题讨论】:

  • 使用任何通用 PDF 库都可以实现。难道不能让场景更具体吗?例如。你对许可条件和可用预算只字未提。
  • 感谢您的回复。如果需要,将只有一个人需要许可证。最终产品将仅在内部使用。我确实找到了一款支持在名为 Debenu 的特定位置添加链接的产品,价格约为 450 美元。单独为初始运行节省时间是值得的,但它有点过分,因为我只会使用 900 多个函数中的 1 个。最初是在寻找使用 adobe SDK 或类似于开源 python 模块的解决方案。如果可能/可用。只需要一些关于可用内容的指导。
  • ;) 这并没有真正限制选择太多。 @Bobrovski 指向 Docotic。我个人对 iText (Sharp) 更了解,并会指出那里。但我实际上无法根据当前信息对任何通用库投票反对
  • 我遇到过 iTextSharp,但找不到任何代码引用来在 pdf 文件的特定位置放置链接(到另一个 pdf 文件的无边框链接区域)。您能否提供参考或示例。您还可以添加答案而不是评论。可能是一个可能的解决方案,我希望能够选择一个答案。

标签: pdf itext


【解决方案1】:

这是很晚的答案。实际上,我正在寻找上述付费图书馆的免费替代品。我发现以下链接对其他人有帮助。

Apache PDFBox 是一个庞大的 java 库,用于以编程方式创建 pdf。

TomRoush/PdfBox-Android 是 android 实现。您可以找到具有此实现的示例项目。

我已经添加了使用上面的 android 库和示例项目在 pdf 中创建可点击链接的代码。

public void createPdf(View v) {
    PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);

    // Create a new font object selecting one of the PDF base fonts
    PDFont font = PDType1Font.HELVETICA;
    // Or a custom font
    //try {
    //  PDType0Font font = PDType0Font.load(document, assetManager.open("MyFontFile.TTF"));
    //} catch(IOException e) {
    //  e.printStackTrace();
    //}

    PDPageContentStream contentStream;

    try {
        // Define a content stream for adding to the PDF
        contentStream = new PDPageContentStream(document, page);

        String preText = "Icons made by ";
        String linkText = "My_Site";

        float upperRightX = page.getMediaBox().getUpperRightX();
        float upperRightY = page.getMediaBox().getUpperRightY();
        // Write linkText in blue text
        contentStream.beginText();
        contentStream.setNonStrokingColor(15, 38, 192);
        contentStream.setFont(font, 18);
        contentStream.moveTextPositionByAmount( 0, upperRightY-20);
        contentStream.drawString(preText + linkText);
        contentStream.endText();

        // create a link annotation
        PDAnnotationLink txtLink = new PDAnnotationLink();

        // set up the markup area
        float offset = (font.getStringWidth(preText) / 1000) * 18;
        float textWidth = (font.getStringWidth(linkText) / 1000) * 18;
        PDRectangle position = new PDRectangle();
        position.setLowerLeftX(offset);
        position.setLowerLeftY(upperRightY - 24f);
        position.setUpperRightX(offset + textWidth);
        position.setUpperRightY(upperRightY -4);
        txtLink.setRectangle(position);

        // add an action
        PDActionURI action = new PDActionURI();
        action.setURI("https://www.**********.com/");
        txtLink.setAction(action);

        // and that's all ;-)
        page.getAnnotations().add(txtLink);

        // load 'Social media' icons from 'vector' resources.
        float padding = 5, startX = 5, startY = upperRightY-100, width = 25, height=25;
        loadVectorIconWithLink(document, page, contentStream, R.drawable.ic_facebook,
                "https://www.facebook.com/My_Name/", startX, startY, width, height);
        startX += (width + padding);
        loadVectorIconWithLink(document, page, contentStream, R.drawable.ic_instagram,
                "https://www.instagram.com/My_Name", startX, startY, width, height);

        // Make sure that the content stream is closed:
        contentStream.close();

        // Save the final pdf document to a file
        String path = root.getAbsolutePath() + "/Download/Created.pdf";
        document.save(path);
        document.close();
        tv.setText("Successfully wrote PDF to " + path);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void loadVectorIconWithLink( PDDocument theDocument,
                                     PDPage thePage,
                                     PDPageContentStream theContentStream,
                                     @DrawableRes int theDrawableId,
                                     String theUriString,
                                     float x, float y, float width, float height
                                     ) throws IOException
{
    Bitmap alphaImage = getBitmapFromDrawable(this, theDrawableId);
    PDImageXObject alphaXimage = LosslessFactory.createFromImage(theDocument, alphaImage);
    theContentStream.drawImage(alphaXimage, x, y, width, height );

    // create a link annotation
    PDAnnotationLink iconLink = new PDAnnotationLink();
    PDRectangle position = new PDRectangle( x, y, width, height );
    iconLink.setRectangle(position);

    // add an action
    PDActionURI action1 = new PDActionURI();
    action1.setURI(theUriString);
    iconLink.setAction(action1);

    // and that's all ;-)
    thePage.getAnnotations().add(iconLink);
}

public static Bitmap getBitmapFromDrawable(Context context, @DrawableRes int drawableId) {
    Drawable drawable = AppCompatResources.getDrawable(context, drawableId);

    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof VectorDrawableCompat || drawable instanceof VectorDrawable) {
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    } else {
        throw new IllegalArgumentException("unsupported drawable type");
    }
}

【讨论】:

  • 此解决方案是否有助于添加指向现有 PDF 文件的链接?还是仅创建。问题是有大量用于 PDF 的仅创建库。而且很少有人能够编辑预先存在的 PDF。
  • @Gherman 我认为此代码仅用于创建新的 pdf 文档。
  • 可以修改PDF文件添加链接,使用load代替新建PDDocument:val document = PDDocument.load(filePath) val page = document.getPage(0)
  • 我必须在这个版本中使用 com.tom_roush:pdfbox-android:1.8.10.3 因为新版本不适合我。
  • @jachumbelechao,感谢您的评论。这将帮助所有用户。
【解决方案2】:

您可能要添加至少三种类型的链接:指向同一文档中的页面的链接、指向其他 PDF 文档中的页面的链接、指向网络上 URL 的链接。

Docotic.Pdf library 可以添加任何这些类型的链接(请注意,我是该库的开发人员之一)。以下是两个相关示例:

没有关于如何在其他在线发布的 PDF 文档中创建页面链接的示例,但如果您需要此类示例,您可以随时联系支持人员。

【讨论】:

  • 感谢您的回复。我会看看这个库。
【解决方案3】:

在继续搜索并没有找到任何其他有前途的开源解决方案后,我选择了Debenu Quick PDF Library。我使用的具体功能如下:

这两个库函数每周为我节省的时间是值得的。我相信我会找到其他 900 多个 PDF 函数的其他用途

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 2016-01-05
    • 2013-10-07
    • 2018-06-19
    • 2011-12-21
    • 2013-07-15
    • 2014-01-12
    • 1970-01-01
    相关资源
    最近更新 更多