How to embed font in PDF created from HTML with iText and Flying Saucer?
Asked Answered
C

4

16

I have problem with embedding Polish fonts into PDF converted from HTML.

My HTML code have style in body:

<BODY style="font-family: Tahoma, Arial, sans-serif;font-size : 8pt;">

I tried 2 ways of converting such HTML into PDF:

  • FOP with htmlcleaner
  • iText with flying-saucer

For FOP I can add all used fonts into its config file and then created PDF have those fonts embedded (if font is used in HTML). In resulting PDF I have Tahoma font in Identity-H encoding. It looks good -- all Polish letters are displayed as expected.

Then I tried such conversion with iText: seems simplier because I do not need to create transformation for every HTML. Unfortunately I don't know how to embed used fonts into resulting PDF. Most examples I found create PDF from scratch and I don't know how to apply those methods to the Flying Saucer ITextRenderer or other object used in conversion.

My current code tries to add fonts in PDFCreationListener.preOpen() by getting ITextFontResolver and adding font fs.addFont(path, true);. But all .pdf I create do not have fonts I want.

The second problem is that result PDF do not have Polish letters. Is it problem in Flying Saucer or in iText? Acrobat shows that created PDF document uses Helvetica with Ansi encoding and ArialMT as font. I think this Ansi encoding is not good. How can I set Polish encoding (Identity-H)?

Conservatism answered 23/9, 2011 at 7:3 Comment(0)
C
3

My mistake was to use FontResolver.addFont() in PDFCreationListener.preOpen(). I moved it just before renderer.layout(); and it works now!

Conservatism answered 17/10, 2011 at 7:1 Comment(1)
Hey, I have a same problem and I tried this code renderer.getFontResolver().addFont("c:/simsun.ttf", "UTF-8",BaseFont.EMBEDDED);//I also tried with arialuni.ttf but it doesn't workHydatid
M
21

You may try the -fs-pdf-font-embed, and -fs-pdf-font-encoding css rules.

From the User's Guide:

-fs-pdf-font-embed: use with the value embed inside a font-face rule to have Flying Saucer embed a font file within a PDF document, avoiding the need to call the addFont() method of the FontResolver class

-fs-pdf-font-encoding: use inside a font-face rule to specify the enconding for a custom font you are embedding inside a PDF; takes the name of the encoding as value.

For example in your print css:

@font-face {
    font-family: DejaVu Serif;
    src: url(fonts/DejaVuSerif.ttf);
    -fs-pdf-font-embed: embed;
    -fs-pdf-font-encoding: Identity-H;
}
Marquettamarquette answered 5/10, 2011 at 14:7 Comment(4)
Thanks, I tried this and this don't work. Of course I tried also FontResolver.addFont(), but in result PDF there is no font I wanted.Thunell
Strange, this worked fine for me. Just make sure to use correct src syntax; FS seems to understand only the url() part, not format() or anything else. There must be only one src with only the ttf file. The example above works.Boggart
That worked for me. Added Googles Roboto more detailed using @font-face { font-family: Roboto; src: url(file:///home/fonts/Roboto-Regular.ttf); font-weight: normal; font-style: normal; -fs-pdf-font-embed: embed; -fs-pdf-font-encoding: Identity-H; } and used it by e.g. <body style="font-family: Roboto;">Cleanup
updated link to user guide flyingsaucerproject.github.io/flyingsaucer/r8/guide/…Insensible
D
6

Working example:

Files in the root project directory:

  • Calibri.ttf
  • input.html

Code:

File inputFile = new File("input.html");
File outputFile = new File("example.pdf");

ITextRenderer renderer = new ITextRenderer();

String url = inputFile.toURI().toURL().toString();
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);

renderer.setDocument(url);
renderer.getFontResolver().addFont("Calibri.ttf", BaseFont.IDENTITY_H, true);
renderer.layout();
renderer.createPDF(fileOutputStream);

fileOutputStream.close();       

HTML:

<style type="text/css">
    body {
        font-family: Calibri, sans-serif;
    }
</style>

Surprisingly @font-face css is not needed

Dorty answered 17/10, 2018 at 10:44 Comment(0)
C
3

My mistake was to use FontResolver.addFont() in PDFCreationListener.preOpen(). I moved it just before renderer.layout(); and it works now!

Conservatism answered 17/10, 2011 at 7:1 Comment(1)
Hey, I have a same problem and I tried this code renderer.getFontResolver().addFont("c:/simsun.ttf", "UTF-8",BaseFont.EMBEDDED);//I also tried with arialuni.ttf but it doesn't workHydatid
D
1

If you've tried all the options and it still doesn't work, it's most likely a problem with with a font-family value that doesn't match the file name

You can find out the correct value using FontForge. Open font file in this program, then select the menu item Element -> Font Info. The correct value will be in the Family Name field

Minimum required html code:

<html>
<head>
    <style>
        body {
            font-family: 'Calibri 123', sans-serif;
        }
    </style>
</head>
<body>
<p>
    Hello, Calibri 123
</p>
</body>
</html>

Minimum required java code:

ITextRenderer renderer = new ITextRenderer();
renderer.getFontResolver().addFont("/path/to/font/Calibri.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.setDocumentFromString(/*read html from file*/);
renderer.layout();
renderer.createPDF(/*stream here*/);
Destinee answered 17/8, 2022 at 8:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.