I have to create a PDF file from a HTML source. Currently, I'm coping with problem concerning special (polish) characters in the output file, precisely with their lack.
HTML source:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<table width="100%" border="0.5" align="center" cellpadding="0" style="border-collapse:collapse; border:1px solid black; font-family:Arial, Helvetica, sans-serif; font-size:16px">
<tr>
<td align="center" ><b>Test: ąęłóćńśŁÓŃĆŻŹąśżźłęó</b></td>
</tr>
</table>
Java source:
Document document = new Document(PageSize.A4, 38, 38, 50, 38);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("iTextExample.pdf"));
document.open();
HTMLWorker htmlWorker = new HTMLWorker(document);
htmlWorker.parse(new StringReader(readFileAsString("index.html")));
document.close();
public static String readFileAsString(String filePath) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
try {
long len = new File(filePath).length();
if (len > Integer.MAX_VALUE) {
throw new IOException("File " + filePath + " too large, was " + len + " bytes.");
}
byte[] bytes = new byte[(int) len];
dis.readFully(bytes);
return new String(bytes, "UTF-8");
} finally {
dis.close();
}
}
My question is: how to change default font (Helvetica) to eg. Arial Bold in whole PDF document?
I've tested many examples connected with StyleSheet and none of them worked. I have to change a default font, because there's no polish characters - that's the solution I hope is going to work.
Edit:
class defaultFontProvider extends FontFactoryImp {
private String _default;
public defaultFontProvider(String def) {
_default = def;
}
public Font getFont(String fontName, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {
if (fontName == null || size == 0) {
fontName = _default;
}
return super.getFont(fontName, encoding, embedded, size, style, color, cached);
}
}
The code above embeds arial.ttf
which is OK, but how do I make it the default font (instead of Helvetica) for the whole document.
Then..
Map<String,Object> providers = new HashMap<String, Object>();
defaultFontProvider dfp = new defaultFontProvider("arial.ttf");
providers.put(HTMLWorker.FONT_PROVIDER, dfp);
HTMLWorker htmlWorker = new HTMLWorker(document);
htmlWorker.setProviders(providers);
It will not chage the default font but only that tag where you will apply.
E.g. <Body>
Add style property in html tag
<tag style="font-family: Arial Unicode MS, FreeSans; font-size:16px; font-weight: normal; >Здраво दी फोंट डाउनलोड Ravi Parekh! </tag>
Note: System should found ARIALUNI in XMLWorkerFontProvider
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(html.getBytes(Charset.forName("UTF-8"))), null,Charset.forName("UTF-8"), new XMLWorkerFontProvider("/fonts/"));
sample:
One answer immediately springs to mind: Change iText. Specifically, Font.getCalculatedBaseFont
, line 644.
String fontName = BaseFont.HELVETICA;
Actually, I don't think that will work unless you also change the way fonts are created... Line 712
cfont = BaseFont.createFont(fontName, encoding, false);
Unless a font is one of the "Base 14", you have to provide a path to the font's file rather than a simple font name.
Transform the input such that you add a font definition to the style of any node that contains text.
You can sit on top of FontFactoryImp and simply map blank strings to your font of choice.
class DefaultFontProvider extends FontFactoryImp {
private String default;
public DefaultFontProvider(String def) {
default = def;
}
// I believe this is the correct override, but there are quite a few others.
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {
if (fontName == null || fontName.size() == 0) {
fontName = default;
}
return super.getFont(fontName, encoding, embedded, size, style, color, cached);
}
}
Map<String,Object> providers = new HashMap<String, Object)();
providers.put(HTMLWorker.FONT_PROVIDER, new DefaultFontProvider("Arial Bold"));
myHTMLWorker.setProviders(providers);
This strikes me as the most Technically Sound idea. It's written for the freshly released 5.0.6 version of iText. Previous versions set the font provider via setInterfaceProps()
instead. "Providers" is more of a name change than anything else at this point. I suspect that will no longer be the case in 5.1.
PS: FontFactoryImp
has two public members you might be interested in as well: defaultEncoding
and defaultEmbedding
. You should be able to tweak the defaultEncoding
to something more Polish-friendly. I recommend "Identity-H" (aka BaseFont.IDENTITY_H
), but that does force all your fonts to be embedded subsets, thus ignoring defaultEmbedding
, and making your files a bit larger than if the fonts weren't embedded at all.
Two possible problems:
Explicitly requesting "Helvetica".
To be sure, I suggest stuffing System.out.println(("Requested font: " + fontName);
into the beginning of your getFont function. This will let you see all the font calls, and make sure you have all your fonts replaced correctly. If that's the case, you can just test for it and replace it with _default
.
Your fontFactory might not be finding anything for "Arial Bold" and so falls back to the default (Helvetica again).
I think you need to call dfp.registerDirectories()
. That'll ferret out all the fonts on several different OS's, and let you reference them all by font name rather than by path (which is what a FontFactoryImp is supposed to do in the first place).
In your style tag, perhaps you can use CSS3 to change the font:
<style>
@font-face {
font-family: myFont;
src: url(Filename);
}
</style>
Not sure if this is what you were asking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With