Is there any method to write data to a PDF file using spring batch ItemWriter. I saw a lot of examples for .txt, .xml etc. None for pdf writer. Using spring boot with batch. Thanks in advance.
0
votes
what you meant to say is that Spring Batch doesn't have any inbuilt pdf writers in API ? What is your data source?
– Sabir Khan
I don't know, is there any pdf ItemWriter exist in spring batch or not. Searched a lot but not found any. Reading data from MySQL database using JdbcCursorItemReader.
– Akhil
I don't think a pdf writer is there. you have to use separate APIs for that and create your own writer. What I meant is , it was not clear in your question that you are looking for already implemented pdf writers or something else so edit your question to make it more clear.
– Sabir Khan
2 Answers
2
votes
0
votes
You don't need a ItemWriter to write data to PDF. What you can do is using a processor in between the writer and reader. There are existing API libraries for you to convert DB, XML or JSON into PDF. Here is an example from Tutorials Point, which I found successful in my program to read an XML to DB and, meanwhile create a PDF file.
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.springframework.batch.item.ItemProcessor;
public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {
public static void drawTable(PDPage page, PDPageContentStream contentStream, float y, float margin,
String[][] content) throws IOException {
final int rows = content.length;
final int cols = content[0].length;
final float rowHeight = 50;
final float tableWidth = page.getMediaBox().getWidth() - (2 * margin);
final float tableHeight = rowHeight * rows;
final float colWidth = tableWidth / (float) cols;
final float cellMargin = 5f;
// draw the rows
float nexty = y;
for (int i = 0; i <= rows; i++) {
contentStream.drawLine(margin, nexty, margin + tableWidth, nexty);
nexty -= rowHeight;
}
// draw the columns
float nextx = margin;
for (int i = 0; i <= cols; i++) {
contentStream.drawLine(nextx, y, nextx, y - tableHeight);
nextx += colWidth;
}
// now add the text
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
float textx = margin + cellMargin;
float texty = y - 15;
for (int i = 0; i < content.length; i++) {
for (int j = 0; j < content[i].length; j++) {
String text = content[i][j];
contentStream.beginText();
contentStream.moveTextPositionByAmount(textx, texty);
contentStream.drawString(text);
contentStream.endText();
textx += colWidth;
}
texty -= rowHeight;
textx = margin + cellMargin;
}
}
@Override
public Tutorial process(Tutorial item) throws Exception {
System.out.println("Processing..." + item);
// Creating PDF document object
File f = new File("/Users/zhenxu/Desktop/test.pdf");
PDDocument doc = PDDocument.load(f);
// Creating a blank page
PDPage page = new PDPage();
doc.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
String[][] content = { { "Id", "" + item.getTutorial_id() }, { "Title", item.getTutorial_title() },
{ "Authour", item.getTutorial_author() }, { "Submission Date", item.getSubmission_date() } };
drawTable(page, contentStream, 700, 100, content);
contentStream.close();
doc.save("/Users/zhenxu/Desktop/test.pdf");
System.out.println("Hello");
return item;
}
Here the input item
is the input XML. The job config goes like:
<!-- Defining a job-->
<batch:job id = "helloWorldJob">
<!-- Defining a Step -->
<batch:step id = "step1">
<batch:tasklet>
<!-- try use PDF converter -->
<batch:chunk reader="xmlItemReader" writer="mySqlItemWriter" processor="itemProcessor" commit-interval="10"></batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
You can customize your reader and writer as well to do other kinds of jobs.