I have an SVG file and I need to create a PDF that has the SVG embedded. I tried with Apache PDFBox (see below) but I get an error saying that "SVG files are not supported". Any ideas how to create a PDF with an embedded SVG? It doesn't have to be with PDFBox, and I prefer not to convert the SVG to an image file.
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
PDImageXObject pdImage = PDImageXObject.createFromFile("C:/chart.svg", doc);
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
contentStream.drawImage(pdImage, 70, 250);
contentStream.close();
doc.save("C:/chart.pdf");
doc.close();
Exception in thread "main" java.lang.IllegalArgumentException: Image
type not supported: chart.svg at
org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createFromFileByExtension(PDImageXObject.java:257)
at
org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createFromFile(PDImageXObject.java:202)
at testjava.TestPdfBox.main(TestPdfBox.java:18)
Related
I trying to write some bengali text into a pdf with PDFBox but facing some problem No glyph for U+0053.I have no idea for glyph.
File file = new File("xyz.pdf");
PDDocument document = PDDocument.load(file);
PDPage page = document.getPage(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
PDFont font = PDType0Font.load(document, BengaliPdfGenerationHelloWorld.class.getResourceAsStream("/textloc/Lohit-Bengali.ttf"),true);
contentStream.setFont(font,12);
contentStream.newLineAtOffset();
contentStream.showText(text);
contentStream.endText();
System.out.println("Content added");
contentStream.close();
document.save(new File("new.pdf"));
Exception in thread "main" java.lang.IllegalArgumentException: No glyph for U+0053 (S) in font Lohit-Bengali
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:366)
at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:415)
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:342)
I'm trying to embed a subset of noto-regular in my code. but I keeping on getting:
java.lang.UnsupportedOperationException: OTF fonts do not have a glyf table
at org.apache.fontbox.ttf.OpenTypeFont.getGlyph(OpenTypeFont.java:66)
at org.apache.fontbox.ttf.TTFSubsetter.addCompoundReferences(TTFSubsetter.java:481)
at org.apache.fontbox.ttf.TTFSubsetter.getGIDMap(TTFSubsetter.java:136)
at org.apache.pdfbox.pdmodel.font.TrueTypeEmbedder.subset(TrueTypeEmbedder.java:306)
at org.apache.pdfbox.pdmodel.font.PDType0Font.subset(PDType0Font.java:162)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1138)
I downloaded the font file NotoSansCJK-Regular.ttc from https://www.google.com/get/noto/help/cjk/
Font subsetting works for .ttf fonts, as I haven't had any issues if the document I saved contains no special characters.
EDIT
It appears that true type collection fonts can have shared glyf table (makes sense since the font collection contains Japanese glyphs). So the individual PDType0Font parsed from .ttc can't be treated as an individual font.
I loaded the font using:
ttc.processAllFonts((TrueTypeFont ttf) -> {
PDFont font = PDType0Font.load(doc, ttf, true);
fontList.add(font);
});
I'm guessing that there are extra work I needed to do to make this work, but I can't find any code samples anywhere.
EDIT2
Seems like the problem is that when subsetting specific OpenType font files, (which font collection contains) turns on an internal flag isPostScript. The flag is then checked and process is aborted when getGlyph() is called.
The following code generates the glyf table error when creating the pdf documents
// downloaded from Noto project site
String OTF_FILE = "./src/test/resources/NotoSansJP-Regular.otf";
PDDocument doc = new PDDocument();
PDFont otf = null;
try (InputStream inputStream = new FileInputStream(new File(OTF_FILE))) {
otf = PDType0Font.load(doc, new OTFParser().parse(inputStream), true);
PDPage page = new PDPage();
PDPageContentStream stream = new PDPageContentStream(doc, page);
stream.setFont(otf, 10f);
stream.beginText();
stream.newLineAtOffset(100f, 600f);
stream.showText("二ろほス反2化みた大第リきやね景手ハニエ者性ルヤリウ円脱");
stream.endText();
stream.close();
doc.addPage(page);
doc.save("test.pdf");
} catch (IOException iox) {
// failed
}
but it will generate the pdf fine as soon as I set the subsetting parameter to true in the PDType0Font.load call
Similarily if I load the otf font through the collection:
String OTF_FILE = "./src/test/resources/NotoSansCJK-Regular.ttc";
PDDocument doc = new PDDocument();
PDFont otf = null;
try (InputStream inputStream = new FileInputStream(new File(OTF_FILE))) {
TrueTypeCollection ttc = new TrueTypeCollection(inputStream);
otf = PDType0Font.load(doc, ttc.getFontByName("NotoSansCJKjp-Regular"), true);
PDPage page = new PDPage();
PDPageContentStream stream = new PDPageContentStream(doc, page);
stream.setFont(otf, 10f);
stream.beginText();
stream.newLineAtOffset(100f, 600f);
stream.showText("二ろほス反2化みた大第リきやね景手ハニエ者性ルヤリウ円脱");
stream.endText();
stream.close();
doc.addPage(page);
doc.save("test.pdf");
} catch (IOException iox) {
// failed
}
I either need to embed the whole font or subsetting will throw the error
EDIT 3
I ended up circumvent this by downloading the OTF font from "Language-specific OpenType/CFF (OTF)", which contains characters from all 4 regions and converted it using otf2ttf from fonttools
I am using PdfBox to generate pdf with an existing Pdf containing the template which has to be used for every Pdf that i want to generate.
But When i try to load the template pdf and wants to write something in it, all previous contains were removed.
So i want both the content should be shown.
Please suggest any solution for it.
Here is the code i am trying to do :
//Loading an existing document
File file = new File("/home/spaneos/ScoringReports-TM-110617.pdf");
PDDocument document = PDDocument.load(file);
//Retrieving the pages of the document
PDPage page = document.getPage(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
//Begin the Content stream
contentStream.beginText();
//Setting the font to the Content stream
contentStream.setFont( PDType1Font.TIMES_ROMAN, 16 );
//Setting the leading
contentStream.setLeading(14.5f);
//Setting the position for the line
contentStream.newLineAtOffset(25, 725);
String text1 = "This is an example of adding text to a page in the pdf document.we can add as many lines";
String text2 = "as we want like this using the ShowText() method of the ContentStream class";
//Adding text in the form of string
contentStream.showText(text1);
contentStream.newLine();
contentStream.showText(text2);
//Creating PDImageXObject object
PDImageXObject pdImage = PDImageXObject.createFromFile("/home/spaneos/Downloads/man-161282_960_720.png",document);
//creating the PDPageContentStream object
PDPageContentStream contents = new PDPageContentStream(document, page);
contentStream.endText();
System.out.println("Content added");
//Closing the PDPageContentStream object
contents.close();
//Closing the content stream
contentStream.close();
//Saving the document
document.save(System.getProperty("user.dir").concat("/PdfBox_Examples/sample.pdf"));
//Closing the document
document.close();
You create the PDPageContentStream instances like this
PDPageContentStream contentStream = new PDPageContentStream(document, page);
[...]
PDPageContentStream contents = new PDPageContentStream(document, page);
Creating it using this constructor replaces any existing content streams with the new one. Instead use this one:
PDPageContentStream contents = new PDPageContentStream(document, page, AppendMode.APPEND, true, true);
AppendMode.APPEND here tells PDFBox to append the new stream, the first true tells it to compress the stream, and the second true tells it to reset the graphics state at the start of your added stream.
Furthermore, you don't really use the second content stream...
I am experiencing problems with TTF fonts loaded for generating PDFs which eventually result in too many open files on Linux. The PDFBox version I tested last was 2.0.0-RC3.
Basically for each PDF I create a document and load two fonts which I want to use. After the document is generated I close all the resources, but the file descriptors for both fonts remain open.
My question is how do I close these two files?
This is my basic code:
doc = new PDDocument();
page = new PDPage(PDRectangle.A4);
doc.addPage(page);
PDFont font = PDType0Font.load(doc, new File(settings.getProperty("font.location")));
PDFont boldFont = PDType0Font.load(doc, new File(settings.getProperty("bold.font.location")));
PDPageContentStream content = new PDPageContentStream(doc, page);
// add content stuff
content.close();
bos = new ByteArrayOutputStream();
doc.save(bos);
bos.flush();
byte[] bytes = bos.toByteArray();
doc.close();
I'm trying to convert a TIFF to a PDF using Apache Imaging and PDFBox. Everything I've tried results in a blank (but non-zero-byte) pdf.
There are some examples in other SO questions like Add BufferedImage to PDFBox document and PDFBox draw black image from BufferedImage which I've tried.
I know the buffered image that I'm reading from the TIFF is valid because I can display it and see it in a JFrame.
I've also tried a PDFJpeg instead of a PDFPixelMap, and contentStream.drawImage() instead of .drawXObject(), the result is always the same.
I also tried creating the PDXObjectImage before the content stream and writing multiple images as recommended in Can't add an image to a pdf using PDFBox, the result is still the same. The output file is larger when I write the image multiple times, so it's doing "something" but I don't know what it is.
How can I write a BufferedImage to a page on a PDF using PDFBox?
try(PDDocument document = new PDDocument();ByteArrayOutputStream outputStream = new ByteArrayOutputStream())
{
PDPage blankPage = new PDPage();
document.addPage( blankPage );
// PDXObjectImage pdImage = new PDJpeg(document, image);
PDXObjectImage pdImage = new PDPixelMap(document, image);
// contentStream.drawImage(pdImage, 5, 300);
PDPageContentStream contentStream = new PDPageContentStream(document, blankPage);
contentStream.drawXObject(pdImage, 5, 5, 100, 100);
document.save("test.pdf");
contentStream.close();
}
catch(COSVisitorException ex) {
throw new IOException(ex);
}