Add links to PDF programmatically

2019-06-13 19:11发布

问题:

I have about 180 PDF files that are generated from a geodatabase. I would like to programmatically add links as hot spots (no text) at the top, bottom, left and right as needed to navigate to the adjoining page files. I would also like to add links over a 3x3 grid in the lower left corner of the page for additional navigation. The grid is already in the existing PDF just no links. Total there will be a possible 14 links added to each page

I am open to suggestions as to how to go about this. I am using Acrobat Pro XI, and I am familiar with various programing languages python, vb.net, C#... Just no experience working directly with PDF files.

回答1:

There are at least three types of links you might want to add: links to pages within the same document, links to pages in other PDF document, links to URLs on the web.

Docotic.Pdf library can add links of any of these types (please note that I am on of the developers of this library). Here are two relevant examples:

  • Create link to page
  • Create hyperlink

There are no examples for how to create links to pages in an other PDF document published online, but you can always contact support if you need such an example.



回答2:

After continuing to search and not finding any other promising open source solutions I went with Debenu Quick PDF Library. The specific functions I used are are noted below:

  • AddLinkToFile
  • AddLinkToPage
  • Other annotations and hotspot links

The time that the two library functions are going to save me weekly is worth the cost alone. I am sure I will find other use for the other 900+ PDF functions



回答3:

This is very late answer. Actually I was searching for free alternative to above paid libraries. I found the following links which can be helpful to others.

Apache PDFBox is a vast java library to create pdf programmatically.

TomRoush/PdfBox-Android is it's android implementation. You can find the sample project with this implementation.

I have added the code for creating clickable links in pdf by using above android library and sample project.

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 itext