/**
* OpenKM, Open Document Management System (http://www.openkm.com)
* Copyright (c) 2006-2011 Paco Avila & Josep Llort
*
* No bytes were intentionally harmed during the development of this application.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.openkm.util;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import bsh.EvalError;
import bsh.Interpreter;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PRAcroForm;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
import de.svenjacobs.loremipsum.LoremIpsum;
import freemarker.template.TemplateException;
/**
* http://itextpdf.sourceforge.net/howtosign.html
*
* @author pavila
*/
public class PDFUtils {
private static Logger log = LoggerFactory.getLogger(PDFUtils.class);
public static int LAYER_UNDER_CONTENT = 0;
public static int LAYER_OVER_CONTENT = 1;
/**
* Stamp PDF document with image watermark
*/
public static void stampImage(InputStream input, byte[] image, OutputStream output) throws FileNotFoundException,
DocumentException, EvalError, IOException {
log.debug("stampImage({}, {}, {})", new Object[] { input, image, output });
stampImage(input, image, LAYER_UNDER_CONTENT, 0.3f, "PAGE_CENTER - IMAGE_WIDTH / 2", "PAGE_MIDDLE - IMAGE_HEIGHT / 2", output);
}
/**
* Stamp PDF document with image watermark
*/
public static void stampImage(InputStream input, byte[] image, int layer, float opacity, String exprX, String exprY,
OutputStream output) throws FileNotFoundException, DocumentException, EvalError, IOException {
log.debug("stampImage({}, {}, {}, {}, {}, {}, {})", new Object[] { input, image, layer, opacity, exprX, exprY, output });
Image img = Image.getInstance(image);
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, output);
PdfGState gs = new PdfGState();
gs.setFillOpacity(opacity);
gs.setStrokeOpacity(opacity);
int numPages = reader.getNumberOfPages();
int count = 0;
while (count++ < numPages) {
Interpreter i = new Interpreter();
i.set("IMAGE_WIDTH", (int) img.getWidth());
i.set("IMAGE_HEIGHT", (int) img.getHeight());
i.set("PAGE_WIDTH", (int) reader.getPageSizeWithRotation(count).getWidth());
i.set("PAGE_HEIGHT", (int) reader.getPageSizeWithRotation(count).getHeight());
i.set("PAGE_CENTER", (int) reader.getPageSizeWithRotation(count).getWidth() / 2);
i.set("PAGE_MIDDLE", (int) reader.getPageSizeWithRotation(count).getHeight() / 2);
int evalX = (Integer) i.eval(exprX);
int evalY = (Integer) i.eval(exprY);
log.debug("evalX: {}", evalX);
log.debug("evalY: {}", evalY);
img.setAbsolutePosition(evalX, evalY);
PdfContentByte cb = null;
if (layer == LAYER_UNDER_CONTENT) {
cb = stamper.getUnderContent(count);
} else if (layer == LAYER_OVER_CONTENT) {
cb = stamper.getOverContent(count);
} else {
throw new IllegalArgumentException();
}
cb.saveState();
cb.setGState(gs);
cb.addImage(img);
cb.restoreState();
}
stamper.close();
}
/**
* Stamp PDF document with text watermark
*/
public static void stampText(InputStream input, String text, OutputStream output) throws FileNotFoundException,
DocumentException, EvalError, IOException {
log.debug("stampText({}, {}, {})", new Object[] { input, text, output });
stampText(input, text, LAYER_UNDER_CONTENT, 0.5f, 100, Color.RED, 35, Element.ALIGN_CENTER, "PAGE_CENTER", "PAGE_MIDDLE", output);
}
/**
* Stamp PDF document with text watermark
*/
public static void stampText(InputStream input, String text, int layer, float opacity, int size, Color color,
int rotation, int align, String exprX, String exprY, OutputStream output) throws FileNotFoundException,
DocumentException, EvalError, IOException {
log.debug("stampText({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})", new Object[] { input, text, layer, opacity, size, color, rotation, align, exprX, exprY, output });
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, output);
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(opacity);
gs.setStrokeOpacity(opacity);
int numPages = reader.getNumberOfPages();
int count = 0;
while (count++ < numPages) {
Interpreter i = new Interpreter();
i.set("PAGE_WIDTH", (int) reader.getPageSizeWithRotation(count).getWidth());
i.set("PAGE_HEIGHT", (int) reader.getPageSizeWithRotation(count).getHeight());
i.set("PAGE_CENTER", (int) reader.getPageSizeWithRotation(count).getWidth() / 2);
i.set("PAGE_MIDDLE", (int) reader.getPageSizeWithRotation(count).getHeight() / 2);
int evalX = (Integer) i.eval(exprX);
int evalY = (Integer) i.eval(exprY);
log.debug("evalX: {}", evalX);
log.debug("evalY: {}", evalY);
PdfContentByte cb = null;
if (layer == LAYER_UNDER_CONTENT) {
cb = stamper.getUnderContent(count);
} else if (layer == LAYER_OVER_CONTENT) {
cb = stamper.getOverContent(count);
} else {
throw new IllegalArgumentException();
}
cb.saveState();
cb.setColorFill(color);
cb.setGState(gs);
cb.beginText();
cb.setFontAndSize(bf, size);
cb.showTextAligned(align, text, evalX, evalY, rotation);
cb.endText();
cb.restoreState();
}
stamper.close();
reader.close();
}
/**
* Fill PDF form
* @throws
*/
@SuppressWarnings("rawtypes")
public static void fillForm(InputStream input, Map<String, Object> values,
OutputStream output) throws FileNotFoundException, DocumentException, TemplateException,
IOException {
log.debug("fillForm({}, {}, {})", new Object[] { input, values, output });
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, output);
AcroFields fields = stamper.getAcroFields();
PRAcroForm form = reader.getAcroForm();
boolean formFlattening = false;
if (form != null) {
for (Iterator it = form.getFields().iterator(); it.hasNext(); ) {
PRAcroForm.FieldInformation field = (PRAcroForm.FieldInformation) it.next();
String fieldValue = fields.getField(field.getName());
log.debug("Field: {}, Value: {}", field.getName(), fieldValue);
if (fieldValue != null && !fieldValue.equals("")) {
if (values.containsKey(field.getName())) {
String result = TemplateUtils.replace("PDF_FILL_FORM", fieldValue, values);
log.debug("Set to '{}'", result);
fields.setField(field.getName(), result);
stamper.partialFormFlattening(field.getName());
formFlattening = true;
}
} else {
Object value = values.get(field.getName());
if (value != null) {
log.debug("Set to '{}'", value);
fields.setField(field.getName(), value.toString());
stamper.partialFormFlattening(field.getName());
formFlattening = true;
}
}
}
}
stamper.setFormFlattening(formFlattening);
stamper.close();
reader.close();
}
/**
* List form fields
*/
@SuppressWarnings("rawtypes")
public static List<String> listFormFields(String input) throws FileNotFoundException, DocumentException,
IOException {
log.debug("listFormFields({})", input);
List<String> formFields = new ArrayList<String>();
PdfReader reader = new PdfReader(input);
PRAcroForm form = reader.getAcroForm();
if (form != null) {
for (Iterator it = form.getFields().iterator(); it.hasNext(); ) {
PRAcroForm.FieldInformation field = (PRAcroForm.FieldInformation) it.next();
formFields.add(field.getName());
}
}
reader.close();
log.debug("listFormFields: {}", formFields);
return formFields;
}
/**
* Generate sample PDF
*/
public static void generateSample(int paragraphs, OutputStream os) throws DocumentException {
LoremIpsum li = new LoremIpsum();
Document doc = new Document(PageSize.A4, 25, 25, 25, 25);
PdfWriter.getInstance(doc, os);
doc.open();
for (int i=0; i<paragraphs; i++) {
doc.add(new Paragraph(li.getParagraphs()));
}
doc.close();
}
}