iText doesn't like my special characters - java

I'm trying to generate a pdf file using iText.
The file gets produced just fine, but I can seem to use special characters like german ä, ö, ...
The sentence I want to be written is (for example)
■ ...ä...ö...
but the output is
■...ä...ö...
(I had to kind of blur the sentences, but I guess you see what I'm talking about...)
Somehow this black block-thing and all "Umlaute" can't be generated ...
The font used is the following:
private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12,
Font.BOLD);
So there should be no problem about the font not having these characters...
I'm using IntelliJ Idea to develop, the encoding of the .java file is set to UTF-8, so there should be no problem too...
I'm kind of lost here; does anyone know what i may do to get it working?
Thanks in advance and greetz
gilaras
---------------UPDATE---------------
So here's (part of) the code:
#Controller
public class Generator {
...
Font font = new Font(Font.FontFamily.TIMES_ROMAN, 9f, Font.BOLD);
...
Paragraph intro = new Paragraph("Ich interessiere mich für ...!", font_12_bold);
Paragraph wantContact = new Paragraph("■ Ich hätte gerne ... ", font);
...
Phrase south = new Phrase("■ Süden □ Ost-West ...");
...
#RequestMapping(value = "/generatePdf", method = RequestMethod.POST)
#ResponseBody
public String generatePdf(HttpServletRequest request) throws IOException, DocumentException, com.lowagie.text.DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(FILE));
addMetaData(document);
document.open();
addContent(document, request);
document.add(new Paragraph("äöü"));
document.close();
return "";
}
private void addContent(Document document, HttpServletRequest request)
throws DocumentException {
Paragraph preface = new Paragraph();
preface.setAlignment(Element.ALIGN_JUSTIFIED);
addEmptyLine(preface, 1);
preface.add(new Paragraph("Rückantwort", catFont));
addEmptyLine(preface, 2);
preface.add(intro);
addEmptyLine(preface, 1);
if (request.getParameter("dec1").equals("wantContact")) {
preface.add(wantContact);
} else {
...
}
document.add(preface);
}
private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
private static void addMetaData(Document document) {
document.addTitle("...");
document.addSubject("...");
document.addKeywords("...");
document.addAuthor("...");
document.addCreator("...");
}
}
I had to take some things out, but I kept some Umlaut-character and other special characters, so that you can see, where the problem occurs ... :-)

You might want to try and embed the font using this technique:
BaseFont times = BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(times, 12, Font.BOLD);

Related

How to count the number of tabs need to cover a string

I am trying to create a string by arranging my data in two columns.
String s = "";
List selectedItems = listView.getSelectionModel().getSelectedItems();
s = s + (String) selectedItems.get(0);
String t;
for (int i = 1 ; i<selectedItems.size();i++){
t = (String) selectedItems.get(i);
if (i%2!=0){
s = s + "\t\t\t";
}
else{
s = s + "\n";
}
s = s + (String) t;
}
My idea is to use a code like this for the task. but depending on the length of the strings, I can't get the second column to one line.
I am thinking there is a way to count the number of tabs need to cover one string an change the number of extra tabs I add instead of adding 3 tabs to every line. but I can't figure out how to count this.
how can I fix this problem?
current results:
one two
three four
five six
expected results:
one two
three four
five six
this is the result of after fill the string with " " with a total length of 30.
i am only using jfx to get the data. itextPdf us used to write the string to a pdf
Accordin to this document you have 3 options:
Assuming you have such data:
public static final String[][] DATA = {
{"John Edward Jr.", "AAA"},
{"Pascal Einstein W. Alfi", "BBB"},
};
1: use a table
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(50);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
table.setWidths(new int[]{5, 1});
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.addCell("Name: " + DATA[0][0]);
table.addCell(DATA[0][1]);
table.addCell("Surname: " + DATA[1][0]);
table.addCell(DATA[1][1]);
table.addCell("School: " + DATA[2][0]);
table.addCell(DATA[1][1]);
document.add(table);
document.close();
}
2: use tabs
public void createPdf(String dest) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
document.add(createParagraphWithTab("Name: ", DATA[0][0], DATA[0][1]));
document.add(createParagraphWithTab("Surname: ", DATA[1][0], DATA[1][1]));
document.add(createParagraphWithTab("School: ", DATA[2][0], DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithTab(String key, String value1, String value2) {
Paragraph p = new Paragraph();
p.setTabSettings(new TabSettings(200f));
p.add(key);
p.add(value1);
p.add(Chunk.TABBING);
p.add(value2);
return p;
}
3: use spaces and a monospaced font
public void createPdf(String dest) throws DocumentException, IOException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Name", DATA[0][0]), DATA[0][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Surname", DATA[1][0]), DATA[1][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "School", DATA[2][0]), DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithSpaces(Font font, String value1, String value2) {
Paragraph p = new Paragraph();
p.setFont(font);
p.add(String.format("%-35s", value1));
p.add(value2);
return p;
}
To achieve the desired output you don't need to count anything - you just use System.out.printf:
public class Main {
public static void main(String[] args) {
System.out.printf("%-10s %-10s\n", "test", "test1");
System.out.printf("%-10s %-10s\n", "longertest", "test2");
}
}
Result:
test test1
longertest test2
As was mentioned in the comment - that will not fix a problem if the font that you use is not monospaced, so I would suggest changing the font as well.
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);

Surrogate Chinese Characters Not Displaying iText Java

Using iText 5.5.11 from the maven repo https://mvnrepository.com/artifact/com.itextpdf/itextpdf/5.5.11
public class test {
public static void main(String[] args) throws DocumentException, IOException {
final String text = "BMP: \u6d4b \u8bd5 Surrogate: \uD841\uDF0E \uD841\uDF31 \uD859\uDC02";
BaseFont baseFont = BaseFont.createFont("C:\\Windows\\Fonts\\arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(baseFont, 6.8f);
Document doc = new Document();
PdfWriter.getInstance(doc, new FileOutputStream("out.pdf"));
doc.open();
Paragraph p = new Paragraph();
p.add(new Phrase(text, font));
doc.add(p);
doc.close();
}
}
The non-surrogate characters in the basic multilingual plane are rendered on the resulting pdf, but the surrogate characters are not.
Edit: Also tried with font "STSong-Light" with encoding "UniGB-UCS2-H" (as in examples in book). Same result - surrogate characters missing.
Edit2: Got it to work with "SimSun-ExtB" font
This is usually a sign that the font being used (in this case Arial) does not have the glyphs for your characters.

Itext New Font with Bold and Underline

I am trying to add new font to my pdf which I need to make it bold and underlined..
I can add the new Font, but cannot make it bold and underlined at same time.
I tried the following way..
public class PdfGenerator {
private static final String BASE_FONT = "Trebuchet MS";
private static final String BASE_FONT_BOLDITALIC = "Trebuchet MS BI";
private static final String BASE_FONT_BOLD = "Trebuchet MS B";
private static final Font titlefontSmall = FontFactory.getFont(
BASE_FONT_BOLD, 10, Font.UNDERLINE);
static {
String filePath = "..my font directory";
String fontPath = filePath + "\\" + "trebuc.ttf";
String fontPathB = filePath + "\\" + "TREBUCBD.TTF";
String fontPathBI = filePath + "\\" + "TREBUCBI.TTF";
FontFactory.register(fontPath, BASE_FONT);
FontFactory.register(fontPathB, BASE_FONT_BOLD);
FontFactory.register(fontPathBI, BASE_FONT_BOLDITALIC);
}
public void genMyPdf(String filePath) {
try {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(filePath));
document.open();
Paragraph p = new Paragraph("This should be bold & underline",
titlefontSmall);
document.add(p);
document.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
What am I doing wrong ?
you can define a font object with both styles :
private static final Font SUBFONT = new Font(Font.getFamily("TIMES_ROMAN"), 12, Font.BOLD|Font.UNDERLINE);
Read up on HERE since you are using the IText library.
Basically use chunks then add those chunks to the document.
Chunk underline = new Chunk("Underline. ");
underline.setUnderline(0.1f, -2f); //0.1 thick, -2 y-location
document.add(underline);
I haven't tried it myself so I don't know how it turns out yet. Further reading up on the iText documentation, it seems that you have to define a bold font first and then implement it. THIS TUTORIAL shows an example of bold font usage with iText and making a pdf with bold text. From there, I'm sure you can implement the code above to the bold text and walah!, bold-underlined text :D
You can define your FONT in your class as such:
public final static Font CUSTOM_FONT = new Font(Font.FontFamily.TIMES_ROMAN, 8, Font.BOLD | Font.UNDERLINE);
and then use it as :
paragraph.add(new Phrase( " YOUR TEXT HERE ",PDFCreator.CUSTOM_FONT));
try it
Font fontbold = FontFactory.getFont("Times-Roman", 12, Font.BOLD);
document.add(new Paragraph("Times-Roman, Bold", fontbold));
and Font.UNDERLINE for undeline
You can just use the following to get both bold and underline:-
Chunk buyerOrder = new Chunk("Buyer's Order Number", FontFactory.getFont(FontConstants.TIMES_ROMAN,8,Font.BOLD));
buyerOrder.setUnderline(0.1f, -2f);
Hope it helps! Thanks

How to create a PDF document from languages of Unicode char set regarding using third party Fonts

I'm using PDFBox and iText to create a simple (just paragraphs) pdf document from various languages. Something like :
pdfBox:
private static void createPdfBoxDocument(File from, File to) {
PDDocument document = null;
try {
document = new TextToPDF().createPDFFromText(new FileReader(from));
document.save(new FileOutputStream(to));
} finally {
if (document != null)
document.close();
}
}
private void createPdfBoxDoc() throws IOException, FileNotFoundException, COSVisitorException {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
PDType1Font font = PDType1Font.TIMES_ROMAN;
contentStream.setFont(font, 12);
contentStream.beginText();
contentStream.moveTextPositionByAmount(100, 400);
contentStream.drawString("š");
contentStream.endText();
contentStream.close();
document.save("test.pdf");
document.close();
}
itext:
private static Font blackFont = new Font(Font.FontFamily.COURIER, 12, Font.NORMAL, BaseColor.BLACK);
private static void createITextDocument(File from, File to) {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(to));
document.open();
addContent(document, getParagraphs(from));
document.close();
}
private static void addContent(Document document, List<String> paragraphs) {
for (int i = 0; i < paragraphs.size(); i++) {
document.add(new Paragraph(paragraphs.get(i), blackFont));
}
}
The input files are encoded in UTF-8 and some languages of Unicode char set, like Russian alphabet etc., are not rendered properly in pdf. The Fonts in both libraries don't support Unicode charset I suppose and I can't find any documentation on how to add and use third party fonts. Could please anybody help me out with an example ?
If you are using iText, it has quite good support.
In iText in Action (chapter 2.2.2) you can read more.
You have to download some unicode Fonts like arialuni.ttf and do it like this :
public static File fontFile = new File("fonts/arialuni.ttf");
public static void createITextDocument(File from, File to) throws DocumentException, IOException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(to));
document.open();
writer.getAcroForm().setNeedAppearances(true);
BaseFont unicode = BaseFont.createFont(fontFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
FontSelector fs = new FontSelector();
fs.addFont(new Font(unicode));
addContent(document, getParagraphs(from), fs);
document.close();
}
private static void addContent(Document document, List<String> paragraphs, FontSelector fs) throws DocumentException {
for (int i = 0; i < paragraphs.size(); i++) {
Phrase phrase = fs.process(paragraphs.get(i));
document.add(new Paragraph(phrase));
}
}
arialuni.ttf fonts work for me, so far I checked it support for
BG, ES, CS, DA, DE, ET, EL, EN, FR, IT, LV, LT, HU, MT, NL, PL, PT, RO, SK, SL, FI, SV
and only PDF in Romanian language wasn't created properly...
With PDFBox it's almost the same:
private void createPdfBoxDoc() throws IOException, FileNotFoundException, COSVisitorException {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
PDFont font = PDTrueTypeFont.loadTTF(document, "fonts/arialuni.ttf");
contentStream.setFont(font, 12);
contentStream.beginText();
contentStream.moveTextPositionByAmount(100, 400);
contentStream.drawString("š");
contentStream.endText();
contentStream.close();
document.save("test.pdf");
document.close();
}
However as Gagravarr says, it doesn't work because of this issue PDFBOX-903 . Even with 1.6.0-SNAPSHOT version. Maybe trunk will work. I suggest you to use iText. It works there perfectly.
You may find this answer helpful - it confirms that you can't do what you need with one of the standard type 1 fonts, as they're Latin1 only
In theory, you just need to embed a suitable font into the document, which handles all your codepoints, and use that. However, there's at least one open bug with writing unicode strings, so there's a chance it might not work just yet... Try the latest pdfbox from svn trunk too though to see if it helps!
In my project, I just copied the font that supported UTF8 (or whatever language you want) to a directory (or you can used Windows fonts path) and add some code, it looked like this
BaseFont baseFont = BaseFont.createFont("c:\\a.ttf", BaseFont.IDENTITY_H,true);
Font font = new Font(baseFont);
document.add(new Paragraph("Not English Text",font));
Now, you can use this font to show your text in various languages.
//use this code.Sometimes setfont() willnot work with Paragraph
try
{
FileOutputStream out=new FileOutputStream(name);
Document doc=new Document();
PdfWriter.getInstance(doc, out);
doc.open();
Font f=new Font(FontFamily.TIMES_ROMAN,50.0f,Font.UNDERLINE,BaseColor.RED);
Paragraph p=new Paragraph("New PdF",f);
p.setAlignment(Paragraph.ALIGN_CENTER);
doc.add(p);
doc.close();
}
catch(Exception e)
{
System.out.println(e);
}
}

Inserting greater than or equal symbol in to an iText PDF, ie >=

Does anyone know an easy way to include the greater than or equal symbol in an iText PDF document without resorting to custom fonts?
You need to add the unicode for this character. Also make sure that the char is included in the font you use.
document.add( new Paragraph("\u2265"));
Use the below code for the same. It's work for me.
//symbol for greater or equal then
public void process() throws DocumentException, IOException {
String dest = "/home/ashok/ashok/tmp/hello.pdf";
BaseFont bfont = BaseFont.createFont(
"/home/ashok/ashok/fonts/Cardo-Regular.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
Font font = new Font(bfont, 12);
try {
Document document=new Document();
PdfWriter.getInstance(document,new
FileOutputStream("/home/ashok/ashok/tmp/hello.pdf"));
document.open();
Chunk chunk = new Chunk("\u2265");
Paragraph p = new Paragraph("Mathematical Operators are ",font);
p.add(chunk);
document.add(p);
p = new Paragraph(" ",font);
chunk = new Chunk("\u2264");
p.add(chunk);
document.add(p);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Categories