I have this code which creates a combobox in a PDF file. There are two problems with it.
Special characters (like ö) are displayed properly when the combobox is opened but then are not displayable when the combobox is closed.
When I open the PDF in Acrobat, change the value and save the PDF, the combobox is somehow gone. When I open the PDF again it is not displayed anymore.
Did I mess up something with the PDFBox classes or what may be the problem?
Here is a picture in the opened state:
and here is one in the closed state:
public class ComboTest {
public static void main(String[] args) {
PDFont font = PDType1Font.HELVETICA;
Color color = Color.BLACK;
float fontSize = 12;
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDAcroForm acroForm = new PDAcroForm(document);
PDComboBox comboBox = new PDComboBox(acroForm);
comboBox.setPartialName("test");
String defaultAppearanceString = "/" + font.getName() + " " + fontSize + " Tf "
+ 0 + " " + 0 + " " + 0 + " rg";
comboBox.setDefaultAppearance(defaultAppearanceString);
PDAnnotationWidget widget = new PDAnnotationWidget();
widget.setRectangle(new PDRectangle(200, 200, 100, 20));
widget.setAnnotationFlags(4);
widget.setPage(page);
widget.setParent(comboBox);
List<String> exportValues = new ArrayList<>();
List<String> displayValues = new ArrayList<>();
displayValues.add("öne");
displayValues.add("two");
displayValues.add("thrée");
exportValues.add("1");
exportValues.add("2");
exportValues.add("3");
comboBox.setOptions(exportValues, displayValues);
List<PDAnnotationWidget> widgets = new ArrayList<>();
widgets.add(widget);
try {
page.getAnnotations().add(widget);
} catch (IOException e) {
e.printStackTrace();
}
comboBox.setWidgets(widgets);
try {
FileOutputStream output = new FileOutputStream("test.pdf");
document.save(output);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Near the end of your code, add this:
acroForm.getFields().add(comboBox);
document.getDocumentCatalog().setAcroForm(acroForm);
this makes sure that your acroform and its field is known to the PDF.
Re the special character, replace the name of the Helvetica font with "Helv", which is a standard name for Adobe.
Better, cleaner solution: set up the default resources.
PDResources dr = new PDResources();
dr.put(COSName.getPDFName("Helv"), font);
acroForm.setDefaultResources(dr);
Instead of "Helv" you can also use COSName.getPDFName(font.getName()), but it has to be the same in your default appearance string.
So the full code is now:
public class ComboTest
{
public static void main(String[] args)
{
PDFont font = PDType1Font.HELVETICA;
Color color = Color.BLACK;
float fontSize = 12;
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDAcroForm acroForm = new PDAcroForm(document);
PDComboBox comboBox = new PDComboBox(acroForm);
comboBox.setPartialName("test");
// Helv instead of Helvetica
String defaultAppearanceString = "/Helv " + fontSize + " Tf "
+ 0 + " " + 0 + " " + 0 + " rg";
comboBox.setDefaultAppearance(defaultAppearanceString);
PDAnnotationWidget widget = new PDAnnotationWidget();
widget.setRectangle(new PDRectangle(200, 200, 100, 20));
widget.setAnnotationFlags(4);
widget.setPage(page);
widget.setParent(comboBox);
List<String> exportValues = new ArrayList<>();
List<String> displayValues = new ArrayList<>();
displayValues.add("öne");
displayValues.add("two");
displayValues.add("thrée");
exportValues.add("1");
exportValues.add("2");
exportValues.add("3");
comboBox.setOptions(exportValues, displayValues);
List<PDAnnotationWidget> widgets = new ArrayList<>();
widgets.add(widget);
try
{
page.getAnnotations().add(widget);
}
catch (IOException e)
{
e.printStackTrace();
}
comboBox.setWidgets(widgets);
// new
acroForm.getFields().add(comboBox);
document.getDocumentCatalog().setAcroForm(acroForm);
PDResources dr = new PDResources();
dr.put(COSName.getPDFName("Helv"), font);
acroForm.setDefaultResources(dr);
try
{
FileOutputStream output = new FileOutputStream("test.pdf");
document.save(output);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Related
I coded an app that stores texts in Room db and the user can create a pdf file contains selected texts retrieved from the db. I'm using PDFbox for creating the pdf files but PDFbox doesn't create new pages automatically as needed. I want the app to create pages in a given pdf file dynamically.
Here is my code:
public void writeDataIntoFile() {
if (adapter.getItemCount()> 0) {
String filePath = createFile();
Log.d("saving pdf", filePath);
PDFBoxResourceLoader.init(getApplicationContext());
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
PDFont font = PDType1Font.TIMES_ROMAN;
document.addPage(page);
PDPageContentStream contentStream;
try {
// Define a content stream for adding to the PDF
contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setStrokingColor(44, 61, 79);
contentStream.setFont(font, 18);
contentStream.setLeading(14.5f);
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
showProgressBar();
executor.execute(() -> {
try { //Background work here - function goes here
//TODO I need to add functions to return words by category
contentStream.newLineAtOffset(25, 770);
contentStream.showText("Category: " + categoryName);
contentStream.newLine();
contentStream.newLine();
contentStream.setNonStrokingColor(15, 38, 192);
contentStream.setFont(font, 12);
for (Word word : adapter.getCurrentList()) {
showMultiLineText(word.getWord() + ": "
+ word.getTranslation(),
550,
contentStream,font,
12);
contentStream.newLine();
count++;
}
contentStream.endText();
contentStream.close();
document.save(filePath);
saved = true;
document.close();
} catch (IOException e) {
Log.d("error", String.valueOf(e));
}
handler.post(() -> {
//UI Thread work here - progress bar goes here
hideProgressBar();
openingPDF(filePath);
Toast.makeText(this, "the file has been saved in /Download/MemorizeWords", Toast.LENGTH_SHORT).show();
});
});
executor.shutdown();
} catch (IOException e) {
Log.d("error", String.valueOf(e));
}
}
else {
Toast.makeText(this, "This category has no words!", Toast.LENGTH_SHORT).show();
}
}
Here is a function checks whether text longer than page width and splits texts if needed:
private void showMultiLineText(String text, int allowedWidth, PDPageContentStream contentStream,
PDFont font,
int fontSize) throws IOException {
List<String> lines = new ArrayList<String>();
String line = "";
// split the text on spaces
String[] words = text.split(" ");
for(String word : words) {
if(!line.isEmpty()) {
line += " ";
}
// check if adding the word to the line surpasses the width of the page
int size = (int) (fontSize * font.getStringWidth(line + word) / 1000);
if(size > allowedWidth) {
// if line + word surpasses the width of the page, add the line without the current word
lines.add(line);
// start new line with the current word
line = word;
} else {
// if line + word fits the page width, add the current word to the line
line += word;
}
}
lines.add(line);
for(String ln : lines) {
count = lines.size();
contentStream.showText(ln);
contentStream.newLine();
}
}```
**Code I am working on to get the text and images getting copied in the PDF but tables are not getting copied from word document
Here i am fetching the text and images first from the word document using apache poi and then i want to write the tables from the word document to pdf document.
Function considering the page size to be A4 as a standard one
Have a look at convertWordToPdf function in the below code .
public static void convertWordToPdf(final String src, final String desc) {
try {
final FileInputStream fs = new FileInputStream(src);
final XWPFDocument doc = new XWPFDocument(fs);
final Document pdfdoc = new Document(PageSize.A4, 72, 72, 72, 72);
final PdfWriter pwriter = PdfWriter.getInstance(pdfdoc,
new FileOutputStream(desc));
pwriter.setInitialLeading(20);
final List<XWPFParagraph> plist = doc.getParagraphs();
pdfdoc.open();
for (int i = 0; i < plist.size(); i++) {
final XWPFParagraph pa = (XWPFParagraph)plist.get(i);
final List<XWPFRun> runs = pa.getRuns();
for (int j = 0; j < runs.size(); j++) {
final XWPFRun run = (XWPFRun) runs.get(j);
final List<XWPFPicture> piclist = run.getEmbeddedPictures();
final Iterator<XWPFPicture> iterator = piclist.iterator();
List<XWPFTable> tabList = doc.getTables();
final Iterator<XWPFTable> tabIterator = tabList.iterator();
while (iterator.hasNext()) {
final XWPFPicture pic = (XWPFPicture) iterator.next();
final XWPFPictureData picdata = pic.getPictureData();
final byte[] bytepic = picdata.getData();
final Image imag = Image.getInstance(bytepic);
imag.scaleAbsoluteHeight(40);
imag.scaleAbsoluteWidth((imag.getWidth() * 30) / imag.getHeight());
pdfdoc.add(imag);
}
final int color = getCode(run.getColor());
Font f = null;
if (run.isBold() && run.isItalic())
f = FontFactory.getFont(FontFactory.TIMES_ROMAN,
run.getFontSize(), Font.BOLDITALIC,
new Color(color));
else if (run.isBold())
f = FontFactory
.getFont(FontFactory.TIMES_ROMAN,
run.getFontSize(), Font.BOLD,
new Color(color));
else if (run.isItalic())
f = FontFactory.getFont(FontFactory.TIMES_ROMAN, run
.getFontSize(), Font.ITALIC, new Color(
color));
else if (run.isStrike())
f = FontFactory.getFont(FontFactory.TIMES_ROMAN,
run.getFontSize(), Font.STRIKETHRU,
new Color(color));
else
f = FontFactory.getFont(FontFactory.TIMES_ROMAN, run
.getFontSize(), Font.NORMAL, new Color(
color));
final String text = run.getText(-1);
byte[] bs;
if (text != null) {
bs = text.getBytes();
final String str = new String(bs, "UTF-8");
final Chunk chObj1 = new Chunk(str, f);
pdfdoc.add(chObj1);
}
}
pdfdoc.add(new Chunk(Chunk.NEWLINE));
}
pdfdoc.close();
} catch (final Exception e) {
e.printStackTrace();
}
Get the tables from the word document and use the Itext API to write them back
List tablesList = doc.getTables();
pdftable = new PdfPTable(3) ; // Table List Move
for (XWPFTable xwpfTable : tablesList) {
pdftable = new PdfPTable(xwpfTable.getRow(0).getTableCells().size()) ;
List row = xwpfTable.getRows();
for (XWPFTableRow xwpfTableRow : row) {
List cell = xwpfTableRow.getTableCells();
for (XWPFTableCell xwpfTableCell : cell) {
if(xwpfTableCell!=null)
{
//table = new Table(cell.size());
pdftable.addCell(xwpfTableCell.getText());
}
}
}
pdfdoc.add(pdftable);
}
I am using iText 7.1.6 to generate the PDF. When I try to run , I get this error document was closed . It is impossible to execute the action.
I checked solutions on Stack Overflow for this, but they are saying it is related to fonts. I modified the fonts by creating instance every time I use it, but even then I get same issue.
How can I resolve this issue?
Please find the below code and exception:
Document doc = null;
PdfPage sourcePage = null;
try (InputStream resource = new FileInputStream(new File(Paths.get("Output").toAbsolutePath()+"/source.pdf"));
PdfReader pdfReader = new PdfReader(resource);
PdfDocument pdfDocument = new PdfDocument(pdfReader)) {
PdfDocumentContentParser contentParser = new PdfDocumentContentParser(pdfDocument);
MarginFinder strategy = contentParser.processContent(1, new MarginFinder());
sourcePage = pdfDocument.getPage(1);
sourcePage.setCropBox(strategy.getBoundingBox());
sourcePage.setMediaBox(strategy.getBoundingBox());
}
#SuppressWarnings("resource")
PdfWriter writer = new PdfWriter(new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/final.pdf"))).setSmartMode(true);
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.setDefaultPageSize(PageSize.A3.rotate());
String fonts[] = {Paths.get("fonts").toAbsolutePath() + "/TREBUC.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBD.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBI.TTF",Paths.get("fonts").toAbsolutePath() + "/TREBUCIT.TTF"};
FontProvider fontProvider = new FontProvider();
Map<String, PdfFont> pdfFontMap = new HashMap<String, PdfFont>();
for (String font : fonts) {
FontProgram fontProgram = FontProgramFactory.createFont(font);
if (font.endsWith("TREBUC.TTF")) {
pdfFontMap.put("NORMAL", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCBD.TTF")) {
pdfFontMap.put("BOLD", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCBI.TTF")) {
pdfFontMap.put("BOLD_ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCIT.TTF")) {
pdfFontMap.put("ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
}
fontProvider.addFont(fontProgram);
}
TestVisualSummaryNew testVisualSummaryNew = new TestVisualSummaryNew();
NormalPageHeader headerHandler = testVisualSummaryNew.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = testVisualSummaryNew.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
doc = new Document(pdfDoc);
doc.setTopMargin(55);
PdfFormXObject xobject = sourcePage.copyAsFormXObject(pdfDoc);
Rectangle xobjectBoundaryBox = xobject.getBBox().toRectangle();
xobject.getPdfObject().put(PdfName.Matrix, new PdfArray(new float[] {1, 0, 0, 1, -xobjectBoundaryBox.getLeft(), -xobjectBoundaryBox.getBottom()}));
Image image = new Image(xobject);
image.setAutoScale(true);
doc.add(image);
System.out.println("Converted to PDF Succesfully >>> source.pdf");
Exception
com.itextpdf.kernel.PdfException: Document was closed. It is
impossible to execute action. at
com.itextpdf.kernel.pdf.PdfDocument.checkClosingStatus(PdfDocument.java:2041)
at
com.itextpdf.kernel.pdf.PdfDocument.getWriter(PdfDocument.java:706)
at
com.itextpdf.kernel.pdf.PdfIndirectReference.getWriter(PdfIndirectReference.java:270)
at com.itextpdf.kernel.pdf.PdfObject.copyTo(PdfObject.java:318) at
com.itextpdf.kernel.pdf.PdfPage.copyAsFormXObject(PdfPage.java:439)
As already indicated in comment to your previous question
You appear to already have closed the source document at that time. It mustn't be closed then to allow copying from it.
Thus, don't close it early, neither explicitly nor by creating it in a try-with-resources:
Document doc = null;
PdfDocument pdfDocument = null; //!!!
PdfPage sourcePage = null;
try ( InputStream resource = new FileInputStream(new File(Paths.get("Output").toAbsolutePath()+"/test.pdf")); ) { //!!!
PdfReader pdfReader = new PdfReader(resource); //!!!
pdfDocument = new PdfDocument(pdfReader); //!!!
PdfDocumentContentParser contentParser = new PdfDocumentContentParser(pdfDocument);
MarginFinder strategy = contentParser.processContent(1, new MarginFinder());
sourcePage = pdfDocument.getPage(1);
sourcePage.setCropBox(strategy.getBoundingBox());
sourcePage.setMediaBox(strategy.getBoundingBox());
//pdfDocument.close(); //!!!
}
try {
#SuppressWarnings("resource")
PdfWriter writer = new PdfWriter(new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/final.pdf"))).setSmartMode(true);
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.setDefaultPageSize(PageSize.A3.rotate());
String fonts[] = {Paths.get("fonts").toAbsolutePath() + "/TREBUC.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBD.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBI.TTF",Paths.get("fonts").toAbsolutePath() + "/TREBUCIT.TTF"};
FontProvider fontProvider = new FontProvider();
Map<String, PdfFont> pdfFontMap = new HashMap<String, PdfFont>();
for (String font : fonts) {
FontProgram fontProgram = FontProgramFactory.createFont(font);
if (font.endsWith("TREBUC.TTF")) {
pdfFontMap.put("NORMAL", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCBD.TTF")) {
pdfFontMap.put("BOLD", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCBI.TTF")) {
pdfFontMap.put("BOLD_ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
} else if (font.endsWith("TREBUCIT.TTF")) {
pdfFontMap.put("ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
}
fontProvider.addFont(fontProgram);
}
TestVisualSummaryNew testVisualSummaryNew = new TestVisualSummaryNew();
NormalPageHeader headerHandler = testVisualSummaryNew.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = testVisualSummaryNew.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
doc = new Document(pdfDoc);
doc.setTopMargin(55);
PdfFormXObject xobject = sourcePage.copyAsFormXObject(pdfDoc);
Rectangle xobjectBoundaryBox = xobject.getBBox().toRectangle();
xobject.getPdfObject().put(PdfName.Matrix, new PdfArray(new float[] {1, 0, 0, 1, -xobjectBoundaryBox.getLeft(), -xobjectBoundaryBox.getBottom()}));
Image image = new Image(xobject);
image.setAutoScale(true);
doc.add(image);
pdfDoc.close();
doc.close();
System.out.println("Converted to PDF Succesfully >>> convertedSvg_" + uuid + ".pdf");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error Occured while converting to PDF = " + e.getMessage());
}
pdfDocument.close(); //!!!
How to add an image over a table with Itext?
I'm using the version 5.5.10
implementation 'com.itextpdf:itextg:5.5.10'
Edit: The image can not be inside the row / column, it must be independent to populate any position on the screen
I'm trying to add an image over the columns of a table, but the result is this:
It always lies below the rows of the column.
To add the image I'm doing so:
public void addImg (int dwb, float x, float y, float desc) {
try{
Bitmap bitmap = dwbToBitmap(context, dwb);
ByteArrayOutputStream stream3 = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream3);
Image image = Image.getInstance(stream3.toByteArray());
stream3.close();
image.scaleToFit(sizeImgFit, sizeImgFit);
image.setAbsolutePosition(35.6f + 10f + x, height-y-sizeImg-(height-desc));
document.add(image);
}catch (Exception e){
log("addImg", e);
}
}
I have already tried to change the order, create the first table and then add the images or vise versa, but it does not work.
Does anyone know how to put the images in position Z above all?
I create the table like this:
public void createTable(ArrayList<String> header, ArrayList<String[]> clients){
float height = 569/header.size();
sizeImg = height;
sizeImgFit = sizeImg - 2;
PdfPTable pdfPTable = new PdfPTable(header.size());
pdfPTable.setWidthPercentage(100);
PdfPCell pdfPCell;
int indexC = 0;
while(indexC < header.size()){
pdfPCell = new PdfPCell(new Phrase(header.get(indexC++), fHeaderText));
pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell.setBackgroundColor(BaseColor.GRAY);
pdfPTable.addCell(pdfPCell);
}
int i = 0;
for(String[] row : clients){
int p = 0;
for(String linha : row){
pdfPCell = new PdfPCell(new Phrase(linha, fText));
pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell.setVerticalAlignment(Element.ALIGN_CENTER);
pdfPCell.setFixedHeight(height);
pdfPTable.addCell(pdfPCell);
log("linha - coluna", i + " - " + p);
p++;
}
i++;
}
//paragraph.add(pdfPTable);
try {
document.add(pdfPTable);
}catch (Exception e){
log("paragraph", e);
}
}
These methods mentioned above are in a class:
public class TemplatePDF {
private Context context;
private File pdfFile;
private Document document;
public PdfWriter pdfWriter;
private Paragraph paragraph;
private Rotate event;
private Font fTitle = new Font(Font.FontFamily.TIMES_ROMAN, 20, Font.BOLD);
private Font fSubTitle = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
private Font fHeaderText = new Font(Font.FontFamily.TIMES_ROMAN, 3, Font.NORMAL, BaseColor.WHITE);
private Font fText = new Font(Font.FontFamily.TIMES_ROMAN, 3);
private Font fHText = new Font(Font.FontFamily.TIMES_ROMAN, 8);
private Font fHighText = new Font(Font.FontFamily.TIMES_ROMAN, 15, Font.BOLD, BaseColor.RED);
private float width = PageSize.A4.getWidth();
private float height = PageSize.A4.getHeight();
public float sizeImg;
public float sizeImgFit;
public TemplatePDF(Context context){
this.context = context;
}
public void openDocument(){
createFile();
try{
document = new Document(PageSize.A4);
pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
event = new Rotate();
document.open();
}catch (Exception e){
Log.e("erro", e.toString());
}
}
private void createFile(){
File folder = new File(Environment.getExternalStorageDirectory().toString(), "PDF");
if(!folder.exists()){
folder.mkdirs();
}
pdfFile = new File(folder, key() + ".pdf");
}
public void closeDocument(){
document.close();
}
...
}
To create PDF, I do so:
//Creating the object
TemplatePDF templatePDF = new TemplatePDF(ficha_pre.this);
templatePDF.openDocument();
templatePDF.addMetaData("Relatório", "Situs", "Woton Sampaio");
templatePDF.addTitles("Relatório", "","Data: " + getDate());
//Creating the table
ArrayList<String> header = new ArrayList<>();
for(int i = 0; i < 55; i++){
header.add(forString(i));
}
ArrayList<pdfItens> itens = arrayItens();
ArrayList<String[]> files = array();
templatePDF.createHeaderFicha(itens);
templatePDF.createTable(header, files);
//Adding image
templatePDF.addImg(R.drawable.ic_a, 0, 20, 566);
The cause for this is that an Image added to the Document is added in a virtual layer underneath that of regular text and tables. Apparently iText developers assumed that text and table elements by default are to be drawn in front of images.
But you can explicitly add the Image to a different virtual layer which is in turn above that of text and tables, in addImg you merely have to replace
document.add(image);
by
pdfWriter.getDirectContent().addImage(image);
Your image in addImg has its AbsolutePosition set. This actually is necessary for images you want to add to the DirectContent because the DirectContent has no idea about current insertion positions or page dimensions.
As an aside, there also is a DirectContentUnder for stuff that shall go even below the layer of Images added via the Document.
i am using following code to generate pdf file, everything is fine and working but i need to add watermark with the pdf file also alternate color to rows generated in pdf table.
response.setHeader("Content-disposition", "attachment; filename=\"" + reportName + ".pdf\"");
response.setContentType("application/pdf");
PdfWriter.getInstance(document,response.getOutputStream());
try {
document.open();
addTitlePage(document, reportName,path);
/* Image image = Image.getInstance(path+"images/abi.png");
image.setAbsolutePosition(40f, 770f);
image.scaleAbsolute(70f, 50f);
document.add(image);*/
//float[] colsWidth = {1.5f,3f,4f,4f,2f};
List<Float> colsWidth = new ArrayList<Float>();
int iterator = 1;
while (iterator <= headerMap.size()) {
if(iterator==1){
colsWidth.add(1.5f);
}else{
colsWidth.add(3f);
}
iterator++;
}
float[] floatArray = ArrayUtils.toPrimitive(colsWidth.toArray(new Float[0]), 0.0F);
PdfPTable table = new PdfPTable(floatArray);
table.setWidthPercentage(98);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
PdfPCell c1 = new PdfPCell();
for (Iterator it = headerMap.keySet().iterator(); it.hasNext();) {
String headerName = (String) headerMap.get(it.next());
c1 = new PdfPCell(new Phrase(headerName, headerFont));
c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(c1);
}
table.setHeaderRows(1);
table = custDAO.creadPDFTable(query, table);
document.add(table);
document.addAuthor(userViewModel.getUsername());
document.addCreationDate();
document.addCreator("POC");
document.close();
response.flushBuffer();
private static void addTitlePage(Document document, String reportName,String path) throws DocumentException, MalformedURLException, IOException {
Paragraph preface = new Paragraph();
addEmptyLine(preface, 1);
/**
* Lets write a big header
*/
Paragraph paragraph = new Paragraph(reportName, titleFont);
paragraph.setAlignment(Element.ALIGN_CENTER);
document.add(paragraph);
/**
* Add one empty line
*/
addEmptyLine(preface, 1);
document.add(preface);
Image image = Image.getInstance(path+"/"+"/abilogo.PNG");
image.setAbsolutePosition(40f, 770f);
image.scaleAbsolute(70f, 50f);
document.add(image);
}
private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
and this the method i use to create pdftable.(rows)
public PdfPTable creadPDFTable(String query,PdfPTable table){
int numberOfColumns=0,sno=1;
Connection connection = getConnection();
if (connection != null) {
try {
PreparedStatement reportTablePS = connection.prepareStatement(query);
ResultSet reportTable_rst = reportTablePS.executeQuery();
ResultSetMetaData reportTable_rsmd = reportTable_rst.getMetaData();
numberOfColumns = reportTable_rsmd.getColumnCount();
while (reportTable_rst.next()) {
table.addCell(new PdfPCell(new Paragraph(String.valueOf(sno), textFont)));
for (int columnIterator = 1; columnIterator <= numberOfColumns; columnIterator++) {
String column = reportTable_rst.getString(columnIterator);
table.addCell(new PdfPCell(new Paragraph(column, textFont)));
}
sno++;
}
} catch (Exception ex) {
ex.printStackTrace();
}finally {
try {
closeConnection(connection, null, null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return table;
}
my main concern is to add watermark also adding alternate color to rows.
Please help to resolve this as i am unable to fix this for long time.
Regards
If you want add an watermark as a image u can use the code below. An other way to add a text watermark is to use annotations.
PdfReader pdfReader = null;
Stream outputStream = null;
PdfStamper pdfStamper = null;
try
{
pdfReader = GetPdfReaderObject();
outputStream = new FileStream(filePathDestination, FileMode.Create, FileAccess.Write, FileShare.None);
pdfStamper = new PdfStamper(pdfReader, outputStream);
PdfLayer layer = new PdfLayer("watermark", pdfStamper.Writer);
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++) {
pdfStamper.FormFlattening = false;
iTextSharp.text.Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex);
PdfContentByte pdfData = pdfStamper.GetOverContent(pageIndex);
pdfData.BeginLayer(layer);
PdfGState graphicsState = new PdfGState();
graphicsState.FillOpacity = 0.5F;
pdfData.SetGState(graphicsState);
pdfData.BeginText();
iTextSharp.text.Image watermarkImage = iTextSharp.text.Image.GetInstance(System.Drawing.Image.FromFile(watermarkImagePath), ImageFormat.Png);
float width = pageRectangle.Width;
float height = pageRectangle.Height;
watermarkImage.SetAbsolutePosition(width / 2 - watermarkImage.Width / 2, height / 2 - watermarkImage.Height / 2);
pdfData.AddImage(watermarkImage);
pdfData.EndText();
pdfData.EndLayer();
}
}
pdfStamper.Close();
outputStream.Close();
outputStream.Dispose();
pdfReader.Close();
pdfReader.Dispose();
} catch (Exception e) {
....
}
}
And not forget to remove the watermark if you want to add an other watermark.