I am trying to save a TextArea as PDF using PDFBox with Java 8. The file gets saved fine and open fine as well. But the file stores the TextArea as one line. I tried to split the TextArea and loop through it with drawString on each split but it's still not working.
Code:
public void saveOutput(MouseEvent e) throws IOException, COSVisitorException {
FileChooser fileChooser = new FileChooser();
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PDF file(*.pdf)", " *.pdf");
fileChooser.getExtensionFilters().add(extFilter);
File savedFile = fileChooser.showSaveDialog(Controller.stage);
if (savedFile != null) {
PDDocument doc = null;
PDPage page = null;
doc = new PDDocument();
page = new PDPage();
doc.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream content = new PDPageContentStream(doc, page);
content.beginText();
content.setFont(font, 8);
content.moveTextPositionByAmount(100, 700);
for (String line : d1CheckedOut.getText().split("\\R+")) {
System.out.println(line+"new line");
content.drawString(line+"\n");
}
content.endText();
content.close();
doc.save(savedFile);
doc.close();
}
}
Related
I am having html content store as a raw string in my database and I like to print it in pdf, but with custom size, for example page size to be 10cm width and 7 com height, not standard A4 format.
Can someone gives me some examples if it is possible.
ByteArrayOutputStream out = new ByteArrayOutputStream();
PDRectangle rec = new PDRectangle(recWidth, recHeight);
PDPage page = new PDPage(rec);
try (PDDocument document = new PDDocument()) {
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.defaultTextDirection(BaseRendererBuilder.TextDirection.LTR);
String htmlContent = "<b>Hello world</b>" + content;
builder.withHtmlContent(htmlContent, "");
document.addPage(page);
builder.usePDDocument(document);
PdfBoxRenderer renderer = builder.buildPdfRenderer();
renderer.createPDFWithoutClosing();
document.save(out);
} catch (Exception e) {
ex.printStackTrace();
}
return new ByteArrayInputStream(out.toByteArray());
This code generates for me 2 files, one small and one A4.
UPDATE:
I tried this one:
try (PDDocument document = new PDDocument()) {
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.defaultTextDirection(BaseRendererBuilder.TextDirection.LTR);
builder.useDefaultPageSize(210, 297, PdfRendererBuilder.PageSizeUnits.MM);
builder.usePdfAConformance(PdfRendererBuilder.PdfAConformance.PDFA_3_A);
String htmlContent = "<b>content</b>";
builder.withHtmlContent(htmlContent, "");
builder.usePDDocument(document);
PdfBoxRenderer renderer = builder.buildPdfRenderer();
renderer.createPDFWithoutClosing();
document.save(out);
} catch (Exception e) {
log.error(">>> The creation of PDF is invalid!");
}
But in this case content is not shown, if I remove useDefaultPageSize, content will be shown
I didn't check this solution before, but try initialise the builder object with your desired page size and document type like below
builder.useDefaultPageSize(210, 297, PdfRendererBuilder.PageSizeUnits.MM);
builder.usePdfAConformance(PdfRendererBuilder.PdfAConformance.PDFA_3_A);
the lib include many PDF format next is PdfAConformance Enum with possible values
PdfAConformance Enum
i am trying to create pdf using pdfbox. i am storing EditText data as html in Sqlite DB.
now i am retrieving data from sqliteDB and creating pdf of that. this data is having marathi language as well as english language.
i am using NotoSerifDevanagari-Bold font and have added it to assets folder. from there i am accessing this font into code. but i am getting error. please find my code and error below.
AssetManager assetManager;
PDFBoxResourceLoader.init(getApplicationContext());
File FilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
assetManager = getAssets();
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDFont font = PDType0Font.load(document, assetManager.open("notoserifdevanagaribold.ttf"));
PDPageContentStream contentStream;
// Define a content stream for adding to the PDF
contentStream = new PDPageContentStream(document, page);
Cursor data = mDatabaseHelper.getDataByDeckname(deckname);
StringBuilder builder=new StringBuilder();
while (data.moveToNext()) {
String front_page_desc = data.getString(3);
String back_page_desc = data.getString(4);
contentStream.beginText();
contentStream.setNonStrokingColor(15, 38, 192);
contentStream.setFont(font, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText(Html.fromHtml(front_page_desc).toString());
contentStream.endText();
contentStream.beginText();
contentStream.setNonStrokingColor(15, 38, 192);
contentStream.setFont(font, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText(Html.fromHtml(back_page_desc).toString());
contentStream.endText();
}
contentStream.close();
String path = FilePath.getAbsolutePath() + "/temp.pdf";
document.save(path);
document.close();
ERROR
W/System.err: java.lang.IllegalArgumentException: No glyph for U+000A in font NotoSerifDevanagari-Bold
I tried so many examples for above error but i am not able to fix the issue. this error i am getting on contentStream.showText(Html.fromHtml(front_page_desc).toString()); line. can someone please help me on above.
As per this link U+000A is the Unicode for new line. Any font will fail if you try to render it.
In order to avoid such error you can try something like this:
String[] lines = text.split("\\n");
for (String line : lines) {
if (!line.isBlank()) {
contentStream.showText(line);
// add new line here if you want to
}
}
I'm trying to create temporary PDF files in Java using PDDocument. I'm employing the following method to create a temporary PDF file.
/* Create a temporary PDF file.*/
private File createPdf(String fileName) throws IOException {
final PDDocument document = new PDDocument();
final File file = File.createTempFile(fileName, ".pdf");
//write it
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write("This is the temporary pdf file content");
bw.close();
document.save(file);
document.close();
return file;
}
This is the test.
#Test
public void testCreateAndMergePdfs() throws IOException {
Collection<File> pdfs = new ArrayList<>(Arrays.asList(createPdf("File1"), createPdf("File2")));
assertFalse(CollectionUtils.isEmpty(pdfs));
PdfPrintPojo pdfPrintPojo = new PdfPrintPojo(pdfs);
File mergedFile = service.createAndMergePDFs(pdfPrintPojo, "Merged");
assertNotNull(mergedFile);
List<File> list = new ArrayList<>(pdfs);
File file1 = list.get(0);
File file2 = list.get(1);
assertTrue(FileUtils.contentEquals(file1, file2));
}
What I'm trying to do here is to create and merge two PDF files. When I run the test, it creates two PDF files in the temp folder, for example, \AppData\Local\Temp\File16375814641476797612.pdf and \AppData\Local\Temp\File24102718409195239661.pdf and the merged file at \AppData\Local\Temp\Merged_merged_3755858389884894769.pdf. But the test fails at
assertTrue(FileUtils.contentEquals(file1, file2));
When I try to open the PDF files in the temp folder, it says that the PDF is corrupted. Also, I have no idea why the files are not being saved as File1 and File2. Can anyone help me with this?
Using Apache PDFBox tutorial, I managed to create a working PDF file(s). The method was changed as follows.
/* Create a temporary PDF file.*/
private File createPdf(String fileName) throws IOException {
// Create a document and add a page to it
final PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
// Create a new font object selecting one of the PDF base fonts
PDFont font = PDType1Font.HELVETICA_BOLD;
// Start a new content stream which will "hold" the to be created content
PDPageContentStream contentStream = new PDPageContentStream(document, page);
// Define a text content stream using the selected font, moving the cursor and drawing the text "Hello World"
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello World");
contentStream.endText();
// Make sure that the content stream is closed:
contentStream.close();
// Save the results and ensure that the document is properly closed:
File file = File.createTempFile(fileName, ".pdf");
document.save(file);
document.close();
return file;
}
As for the test, I took the approach of using PDDocument to load the files, then extract data as String using PDFTextStripper and using assertions on those Strings.
#Test
public void testCreateAndMergePdfs() throws IOException {
Collection<File> pdfs = new ArrayList<>(Arrays.asList(createPdf("File1"), createPdf("File2")));
assertFalse(CollectionUtils.isEmpty(pdfs));
PdfPrintPojo pdfPrintPojo = new PdfPrintPojo(pdfs);
File mergedFile = service.createAndMergePDFs(pdfPrintPojo, "Merged");
assertNotNull(mergedFile);
List<File> list = new ArrayList<>(pdfs);
/* Load the PDF files and extract data as String. */
PDDocument document1 = PDDocument.load(list.get(0));
PDDocument document2 = PDDocument.load(list.get(1));
PDDocument merged = PDDocument.load(mergedFile);
PDFTextStripper stripper = new PDFTextStripper();
String file1Data = stripper.getText(document1);
String file2Data = stripper.getText(document2);
String mergedData = stripper.getText(merged);
/* Assert that data from file 1 and 2 are equal with each other and merged file. */
assertEquals(file1Data, file2Data);
assertEquals(file1Data + file2Data, mergedData);
}
The way you compare the file contents is a bit different, Could you try with below,
#Test
public void testCreateAndMergePdfs() {
Assert.assertEquals(FileUtils.readLines(file1), FileUtils.readLines(file2));
}
Or you can try
byte[] file1Bytes = Files.readAllBytes(Paths.get("Path to File 1"));
byte[] file2Bytes = Files.readAllBytes(Paths.get("Path to File 2"));
String file1 = new String(file1Bytes, StandardCharsets.UTF_8);
String file2 = new String(file2Bytes, StandardCharsets.UTF_8);
assertEquals("The content in the strings should match", file1, file2);
Or
File file1 = new File(file1);
File file2 = new File(file2);
assertThat(file1).hasSameContentAs(file2);
I am trying to convert a unicode Text File to PDF using PDF box.
Task:
My method takes a unicode encoded TextFile as input and output a PDF file.
Problem:
The PDFs that are created have zero bytes. It is not writing anything.
I am using
Apache PDFBox 2.0.6
This is my code:
public class TexttoPDF {
public File texttoPDF(File textFile) throws Exception {
PDDocument document = new PDDocument();
PDPage blankPage = new PDPage();
PDFont font = PDType1Font.TIMES_ROMAN;
PDPageContentStream contentStream = new PDPageContentStream(document, blankPage);
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(textFile), "UTF8"));
String str;
contentStream.beginText();
contentStream.setFont( font, 12 );
contentStream.moveTextPositionByAmount( 100, 700 );
while ((str = in.readLine()) != null) {
contentStream.drawString(str);
}
contentStream.endText();
document.save( pdffile.getName());
contentStream.close();
document.close();
in.close();
return pdffile;
}
}
How this can be fixed ?
Close your content stream before saving, not after saving. So change
document.save( pdffile.getName());
contentStream.close();
to
contentStream.close();
document.save( pdffile.getName());
(This is described in the FAQ)
Also add the page to your document after calling new PDPage():
document.addPage(blankPage);
Trying to write heart symbol in pdf through java code .
This is my input to pdf : ❤️❤️❤️
But pdf generated is empty without anything written.
Using itext to write to pdf.
The Font used is tradegothic_lt_boldcondtwenty.ttf
OutputStream file = new FileOutputStream(fileName);
Document document = new Document(PageSize.A6);
PdfWriter writer = PdfWriter.getInstance(document, file);
document.open();
PdfLayer nested = new PdfLayer("Layer 1", writer);
PdfContentByte cb = writer.getDirectContent();
cb.beginLayer(nested);
ColumnText ct = new ColumnText(cb);
Font font = getFont();
Phrase para1 = new Phrase("❤️❤️❤️",font);
ct.setSimpleColumn(para1,38,0,260,138,15, Element.ALIGN_LEFT);
ct.go();
cb.endLayer();
document.close();
file.close();
private Font getFont() {
final String methodName = "generatePDF";
LOGGER.entering(CLASSNAME, methodName);
Font font = null;
try {
String filename = tradegothic_lt_boldcondtwenty.ttf;
FontFactory.register(filename, filename);
font = FontFactory.getFont(filename, BaseFont.CP1252, BaseFont.EMBEDDED,11.8f);
} catch(Exception exception) {
LOGGER.logp(Level.SEVERE, CLASSNAME, methodName, "Exception Occurred while fetching the Trade Gothic font." + exception);
font = FontFactory.getFont(FontFactory.HELVETICA_BOLD,11.8f);
}
return font;
}
Phrase para1 has the heart correctly. But not able to see in pdf