Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding fonts to Apache Pdfbox?

Is there a way to add additional font styles into Apache Pdfbox?

We're currently trying to work around printing PDFs in our system (currently being done with PDF-Renderer.) I have been looking at various alternatives (pdfbox, jpedal, jPDFPrint)

Our hope is for a free GPL compatible library to use, and as such we're leaning towards pdfbox. I have been able to write some sample code to print out the pdf which 'works'. See below:

PDDocument doc;
try {
        doc = PDDocument.load("test.pdf");
        doc.print();
    } catch (Exception e) {
        // Come up with better thing to do on fail.
        e.printStackTrace();
    }

As I mentioned, this works but the problem I'm running into is that PdfBox doesn't seem to be recognizing the fonts used in the pdf, and as such changes the font being used. As a result the document looks very odd (spacing and character size are different and look bizarre). I routinely see the following log message, or things like it:

Apr 16, 2014 2:56:21 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString WARNING: Changing font on < > from < NimbusMono > to the default font

Does anyone know of a way (or a reference) on how to approach adding a new fonttype into pdfbox? Or barring that, how to change the default font type?

From what I can tell, pdfbox supports 14 standard fonts. Unfortunately NimbusMono is not one of them. Any guidance would be appreciated.

like image 866
K.Niemczyk Avatar asked Apr 16 '14 19:04

K.Niemczyk


3 Answers

The unreleased 2.0 version supports the rendering of embedded fonts. You can get it as a snapshot https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/ or through "svn checkout http://svn.apache.org/repos/asf/pdfbox/trunk/". The API is slightly different from the 1.8.x versions and might change, the best is to look at the code examples. A quick test to see whether your file will be rendered properly is to download the "pdfbox-app" https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/pdfbox-app/2.0.0-SNAPSHOT/ and then run the viewer: java -jar pdfbox-app-2.0.0-20140416.173452-273.jar PDFReader your-file-name.pdf There's also a print feature.

Good luck!

Update 2016: 2.0 release is out, download it here. If you have used the 1.8 version, read the migration guide.

like image 154
Tilman Hausherr Avatar answered Oct 23 '22 13:10

Tilman Hausherr


I came across this post while trying to solve the same problem. The PDFBox 2.0 API documentation isn't great at the moment.

What you're looking for is the FontFileFinder in Fontbox. Make sure you're using the full pdfbox-app jar which includes Fontbox.

I've only tried this on Windows but looking at the classes it seems like it supports the other main operating systems.

Here's a simple example class I wrote that writes out a small bit of text in the bottom left corner of a PDF, using a non-standard font.

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;

import org.apache.fontbox.util.autodetect.FontFileFinder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

public class TestPDFWrite {

    public static void main(String[] args) throws IOException {

        FontFileFinder fontFinder = new FontFileFinder();
        List<URI> fontURIs = fontFinder.find();

        File fontFile = null;

        for (URI uri : fontURIs) {
            File font = new File(uri);
            if (font.getName().equals("CHILLER.TTF")) {
                fontFile = font;
            }
        }

        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);

        PDPageContentStream contentStream = new PDPageContentStream(document, page);
        contentStream.beginText();

        if (fontFile != null) {
            contentStream.setFont(PDType0Font.load(document, fontFile), 12);
        } else {
            contentStream.setFont(PDType1Font.HELVETICA, 12);
        }

        contentStream.newLineAtOffset(10, 10);
        contentStream.showText("Hello World");
        contentStream.endText();
        contentStream.close();
        document.save("C:/Hello World.pdf");
        document.close();
    }
}
like image 3
Column-E Avatar answered Oct 23 '22 12:10

Column-E


I ran into a similar problem with PDFBox. PDFs can be printed in a straightforward way using Java's javax.print package. The following code is slightly modified from the API docs for javax.print.

DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_C6); //letter size
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(flavor, aset);
if (pservices.length > 0) {
   DocPrintJob pj = pservices[0].createPrintJob();
   try {
       FileInputStream fis = new FileInputStream("test.pdf");
       Doc doc = new SimpleDoc(fis, flavor, null);
       pj.print(doc, aset);
   } catch (FileNotFoundException | PrintException e) {
       //do something
   }

This code assumes that the printer can accept a PDF directly but it allows you to bypass PDFBox 1.8 branch's wonky font issues.

like image 1
mttdbrd Avatar answered Oct 23 '22 11:10

mttdbrd