JAVA - font path instead font name in docx - java

I am using Apache POI to generate .docx document. I added external fonts to my project. For example:
String playfairDisplayRegular = this.getClass().getClassLoader().getResource("PlayfairDisplay-Regular.ttf").getFile();
I used playfairDisplayRegular in paragraph. When I mark text in the document in the field with the name of the font is path for example:
/C:/Users/..../Documents...
instead of the font name (the font is working). Any ideas ?
Greetings, Artur

URL.getFile() just returns the file name part (+ optional query part ?...) of the URL.
For resources (files possibly inside a jar, residing on the class path) one should rather not use File, but use an InputStream, whenever possible.
With java.awt.Font:
Font font = Font.createFont(Font.TRUETYPE_FONT,
getClass().getResourceAsStream("/PlayfairDisplay-Regular.ttf"));
In the docx you can now use font.getFamily() (for XSLFTextRun.setFontFamily) and such.
Embedding fonts in the docx:
Meanwhile apache poi might be able to embed fonts (license issue for you!), but doing it yourself should be simple: .docx is a zip format, fonts are in a /fonts/ subdirectory. You can test it in a small docx written in MSWord. Writing the file can be done by a zip file system: "jar:file:/C:/... .docx", and Files.copy.

Using java.awt.Font will be problematic for me, bacause my syntax looks like this:
printParagraph(createParagraphWithAlignment(document, ParagraphAlignment.RIGHT),
"something",
new Font(playfairDisplayRegular, 12, Boolean.TRUE, Boolean.FALSE));
And methods used:
protected XWPFRun printParagraph(XWPFParagraph paragraph, String text, Font font) {
XWPFRun run = paragraph.createRun();
run.setText(text);
run.setFontSize(font.getSize());
run.setBold(font.getBold());
run.setItalic(font.getItalic());
run.setFontFamily(font.getName());
return run;
}
protected XWPFParagraph createParagraphWithAlignment(IBody ibody, ParagraphAlignment alignment) {
XWPFParagraph paragraph = castParagraph(ibody);
paragraph.setAlignment(alignment);
return paragraph;
}

Related

How to convert docx to PDF without split tables

I have dynamics docx with few tables and I'm trying to convert to a PDF. When I converted to PDF then it covers two pages. I use Apache POI XWPF converter in 2.0.2 version.
In docx file everything is okey but when I convert to PDF then tables are spited
Someone have any idea or better library to convert docx to pdf?
PdfOptions options = PdfOptions.getDefault();
options.fontProvider((familyName, encoding, size, style, color) -> {
try {
BaseFont baseFont = BaseFont.createFont("fonts/times.ttf", encoding, BaseFont.EMBEDDED);
return new Font(baseFont, size, style, color);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
PdfConverter.getInstance().convert(document, out, options);
There is no library to convert a doc[x] file into a completely correctly formatted PDF. The only program that can do that is Word itself.
I have achieved this by using the Word API in a PowerShell script:
$document_path = $args[0]
$document_parent_folder = $args[1]
$file_name = $args[2]
$word_app = New-Object -ComObject Word.Application
$document = $word_app.Documents.Open($document_path)
$pdf_filename = "$($document_parent_folder)\$($file_name)"
$document.SaveAs([ref] $pdf_filename, [ref] 17)
$document.Close()
$word_app.Quit()
Yes it is not the best solution and it is heavily dependent on having Microsoft Office installed in the machine and a lot of other problems that accompany this solution... But it is the only solution that formatted my documents exactly how I wanted them.
The script takes three arguments
The path of the document that will be converted
The folder where it is located
The name of the pdf file

PdfBox embed fonts into existing document

I have a pdf file which shows font properties in Okular (or whatever PDF viewer) like that:
Name: Helvetica
Type: Type1
File: /usr/share/fonts/truetype/liberation2/LiberationSans-regular.ttf
Embedded: No
I want to embed Helvetica with PDFBox 2xx without modifying file content (text) itself so it would always available with a file.
Is it possible at all?
I tried something like:
PDDocument document = PDDocument.load(myFile);
InputStream stream = new FileInputStream(new File("/home/user/fonts_temp/Helvetica.ttf"));
PDFont fontToEmbed = PDType0Font.load(document, stream, true);
PDResources resources = document.getPage(pageNumber).getResources();
resources.add(fontToEmbed);
//or use the font from pdfbox:
resources.add(PDType1Font.HELVETICA);
document.save(somewhere);
document.close();
I also tried to call
COSName fontCosName = resources.add(PDType1Font.HELVETICA);
resources.put(fontCosName, font);
What am I doing wrong?
Edit:
#TilmanHausherr thank you for the clue! But I'm still missing something. Currently my code looks like:
PDFont helvetica = PDType0Font.load(document, new FileInputStream(new File("/path/Helvetica.ttf")), false);
...
PDResources resources = page.getResources();
for (COSName fontCosName : resources.getFontNames()){
if(resources.getFont(fontCosName).getName().equals("Helvetica")) {
resources.put(fontCosName, helvetica);
}
}
End result shows
Helvetica CID TrueType Fully Embedded
But the font is not displayed in PDF file at all now. I mean those places where the font is used are literally empty, blank page... Still something is not there.
Font itself was downloaded from here
You'd need to know the name that is currently used in the resources, so check these with resources.getFontNames()
2.
To replace a standard 14 font, use this font object:
PDTrueTypeFont.load(document, file, oldFont.getEncoding() /* or WinAnsiEncoding.INSTANCE which is usually right */ );
this ensures that the same encoding is used as the standard 14 font. (It's different for the Zapf Dingbats and the Symbol font)

Font different in MS Edge than Chrome for PDF when using PDFBox

I have a PDF template created in Acrobat Reader DC which contains a field that I trying to fill with some text. The field has a specific font that I want to keep. I am able to obtain the field and change the value.
However, when I open the PDF in Internet Explorer the font is a default font. The confusing part is that if I open it in Chrome then it shows the correct font. Not sure why that is, any help is appreciated. I am using PDFBox version 2.
(The font works if I don't use Java to edit the file, if I just manually change it inside Acrobat and save the file then it shows correctly.)
See below for the code used.
File file = new File("PDFToReadFrom.pdf");
PDDocument pdDoc = PDDocument.load(file);
PDDocumentCatalog pdCatalog = pdDoc.getDocumentCatalog();
PDAcroForm pdAcroForm = pdCatalog.getAcroForm();
for(PDField pdField : pdAcroForm.getFields()){
pdField.setValue("value");
}
pdDoc.save(new File("test.pdf"));
pdDoc.close();
I suggest you'd better to compare the PDF file (Use Java edited file and the Acrobat generated file), whether they are using the same font.
According to this article, it seems that we could set the font when using PDFBox to create a PDF file.

Embed non-embedded fonts in PDF with IText

So I have the following problem. I receive a PDF file which contains a set of fonts. These fonts are not embedded into the file. Here is a simple example:
I would like to embed these fonts inside the PDF, so they're self-contained and always available. But things don't seem that simple. I'm using IText to do my PDF processing.
I have read and tried the following questions/answers:
how-to-create-pdf-with-font-information-and-embed-actual-font-when-merging-them
embed-truetype-fonts-in-existing-pdf
embed-font-into-pdf-file-by-using-itext
how-to-check-that-all-used-fonts-are-embedded-in-pdf-with-java-itext
Chapter 16.1.4 Replacing a font of the book iText in Action - 2nd Edition
...
But what had gotten me closest was the following example: EmbedFontPostFacto.java (which comes from the book). I was able to embed the Arial font when providing the Arial.ttf file.
But with this, like with other examples, I need the source file of the font in order to embed it. In my case, I don't have the source file. But I might have them on the system however. So I'd like to query my available fonts on the system and see if it corresponds to the given font.
Something of the likes as
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
java.awt.Font[] fonts = e.getAllFonts();
for(java.awt.Font f : fonts){
System.out.println(f.getFontName());
}
But I cannot transform the given java.awt.Font into a RandomAccessFile or a byte[] to be used in order to embed the font file itself. Is there another way for embedding fonts into a PDF, without having the source file of the font itself?
For Windows C:\Windows\Fonts or such contain all font files, and in the explorer shows also font names. So a manual search is feasible.
In java, you have GraphicsEnvironment.getAvailableFontFamilyNames() and Font.getFamilyName() to check for a name from the PDF like "Arial MT."
However a getter for the file is missing from Font.
So list all files of the font directory, and load each file consecutively as Font.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font font = Font.createFont(Font.TRUETYPE_FONT, ttfFile);
ge.registerFont(font); // If you want to load the font.
if (pdfFontName.startsWith(font.getFamilyName()) {
System.out.printf("%s - %s / %s%n", ttfFile.getName(), font.getFamilyName(),
font.getName());
}

Creating Word File With JTextPane Style Option

I want to save the contents of a JTextPane to a word file.
I don't have a problem saving but I can't currently keep some style options such as paragraph styles.
I use these libraries:
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
Lines of code;
System.out.println("Kaydete basıldı");
String text = textPane.getText();
lblNewLabel.setText(text);
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(text);
try {
FileOutputStream dosyaCikis = new FileOutputStream(
"sercan.docx");
document.write(dosyaCikis);
dosyaCikis.close();
} catch (Exception e2) {
e2.printStackTrace();
}
Apache POI or another way, it does not matter, I am waiting for your help.
This example shows how to set various style options:(Apache POI)
SimpleDocument
Example code form the link:
XWPFDocument doc = new XWPFDocument();
XWPFParagraph p1 = doc.createParagraph();
p1.setAlignment(ParagraphAlignment.CENTER);
p1.setBorderBottom(Borders.DOUBLE);
p1.setBorderTop(Borders.DOUBLE);
p1.setBorderRight(Borders.DOUBLE);
p1.setBorderLeft(Borders.DOUBLE);
p1.setBorderBetween(Borders.SINGLE);
p1.setVerticalAlignment(TextAlignment.TOP);
XWPFRun r1 = p1.createRun();
r1.setBold(true);
r1.setText("The quick brown fox");
r1.setBold(true);
r1.setFontFamily("Courier");
r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
r1.setTextPosition(100);
Other examples(styles,images .etc) can be found here:
Example Package
AFAIK the options for writing Word files are limited from standard Java libraries.
You probably want to use a tool that explicitly supports Word formats - the best bet is probably LibreOffice, which is Free software. The LibreOffice API supports Java and other languages.
For a fuller explanation look here:
What's a good Java API for creating Word documents?
However that answer refers to OpenOffice, of which LibreOffice is a more actively developed fork due to management issues over the years.
You could try docx_editor_kit. From the web page:
it can open docx file and reflect the content in JEditorPane (or
JTextPane). Also user can create styled content and store the content
in docx format.
Somewhat related is my docx4all, but it hasn't been updated recently, and it may be overkill for your purposes.
Both of these use docx4j (as opposed to POI).

Categories