1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.sys;
20
21 import java.awt.Color;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.text.SimpleDateFormat;
29 import java.util.Map;
30
31 import org.kuali.rice.krad.util.ObjectUtils;
32
33 import com.lowagie.text.DocumentException;
34 import com.lowagie.text.Element;
35 import com.lowagie.text.Rectangle;
36 import com.lowagie.text.pdf.AcroFields;
37 import com.lowagie.text.pdf.BaseFont;
38 import com.lowagie.text.pdf.PdfContentByte;
39 import com.lowagie.text.pdf.PdfGState;
40 import com.lowagie.text.pdf.PdfReader;
41 import com.lowagie.text.pdf.PdfStamper;
42
43
44
45
46 public class PdfFormFillerUtil {
47
48 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PdfFormFillerUtil.class);
49 private static final SimpleDateFormat FILE_NAME_TIMESTAMP = new SimpleDateFormat("_yyyy-MM-dd_hhmmss");
50
51
52
53
54
55
56
57
58 public static byte[] populateTemplate(InputStream templateStream, Map<String, String> replacementList) throws IOException, DocumentException {
59
60
61
62 if (templateStream == null || replacementList == null) {
63 throw new IllegalArgumentException("All parameters are required, but one or more were null.");
64 }
65
66
67
68
69 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
70 pdfStampValues(templateStream, outputStream, replacementList);
71 return outputStream.toByteArray();
72 }
73
74
75
76
77
78
79
80
81 public static byte[] populateTemplate(File template, Map<String, String> replacementList) throws IOException, DocumentException {
82
83
84
85 if (template == null || replacementList == null) {
86 throw new IllegalArgumentException("All parameters are required, but one or more were null.");
87 }
88
89
90 if (template.exists() == false) {
91 throw new IOException("The template file '" + template.getAbsolutePath() + "' does not exist.");
92 }
93 if (!template.isFile()) {
94 throw new RuntimeException("The template file '" + template.getAbsolutePath() + "' is not a valid file.");
95 }
96 if (!template.canRead()) {
97 throw new RuntimeException("The template file '" + template.getAbsolutePath() + "' cannot be read.");
98 }
99
100
101
102
103 InputStream templateStream = new FileInputStream(template);
104 return populateTemplate(templateStream, replacementList);
105 }
106
107
108
109
110
111
112
113
114
115 private static boolean validListTagFound(String strLine) {
116 boolean valid = true;
117 valid &= strLine.matches("^#[\\S]*$");
118 return valid;
119 }
120
121
122
123
124
125
126
127
128
129 private static void pdfStampValues(InputStream templateStream, OutputStream outputStream, Map<String, String> replacementList) throws IOException {
130 try {
131
132 PdfReader pdfReader = new PdfReader(templateStream);
133
134
135 PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
136
137 AcroFields fields = pdfStamper.getAcroFields();
138 for (Object fieldName : fields.getFields().keySet()) {
139
140 String text = fields.getField(fieldName.toString());
141 String newText = fields.getField(fieldName.toString());
142
143 if (fields.getFieldType(fieldName.toString()) == AcroFields.FIELD_TYPE_TEXT) {
144 newText = replaceValuesIteratingThroughFile(text, replacementList);
145 }
146 else {
147 if (ObjectUtils.isNotNull(replacementList.get(fieldName.toString()))) {
148 newText = replacementList.get(fieldName);
149 }
150 }
151
152 fields.setField(fieldName.toString(), newText);
153 }
154
155
156
157
158 pdfStamper.close();
159
160 }
161 catch (IOException e) {
162 throw new IOException("IO error processing PDF template", e);
163 }
164 catch (DocumentException e) {
165 throw new IOException("iText error processing PDF template", e);
166 }
167 finally {
168
169
170
171 templateStream.close();
172 outputStream.close();
173 }
174 }
175
176
177
178
179
180
181
182
183
184
185 public static byte[] createFinalmarkOnFile(byte[] templateStream, String finalmarkText) throws IOException, DocumentException {
186
187 PdfReader pdfReader = new PdfReader(templateStream);
188
189 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
190
191 PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
192 int n = pdfReader.getNumberOfPages();
193 int i = 1;
194 PdfContentByte over;
195 BaseFont bf;
196 try {
197 bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
198 PdfGState gstate = new PdfGState();
199 while (i <= n) {
200
201 Rectangle pageSize = pdfReader.getPageSizeWithRotation(i);
202 over = pdfStamper.getOverContent(i);
203 over.beginText();
204 over.setFontAndSize(bf, 8);
205 over.setGState(gstate);
206 over.setColorFill(Color.BLACK);
207 over.showTextAligned(Element.ALIGN_CENTER, finalmarkText, (pageSize.width() / 2), (pageSize.height() - 10), 0);
208 over.endText();
209 i++;
210 }
211 pdfStamper.close();
212 }
213 catch (DocumentException ex) {
214 throw new IOException("iText error creating final watermark on PDF", ex);
215 }
216 catch (IOException ex) {
217 throw new IOException("IO error creating final watermark on PDF", ex);
218 }
219 return outputStream.toByteArray();
220 }
221
222
223
224
225
226
227
228
229
230
231 public static byte[] createWatermarkOnFile(byte[] templateStream, String watermarkText) throws IOException, DocumentException {
232
233 PdfReader pdfReader = new PdfReader(templateStream);
234
235 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
236
237 PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
238 int n = pdfReader.getNumberOfPages();
239 int i = 1;
240 PdfContentByte over;
241 BaseFont bf;
242 try {
243 bf = BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
244 PdfGState gstate = new PdfGState();
245 gstate.setFillOpacity(0.5f);
246 while (i <= n) {
247
248 Rectangle pageSize = pdfReader.getPageSizeWithRotation(i);
249 over = pdfStamper.getOverContent(i);
250 over.beginText();
251 over.setFontAndSize(bf, 200);
252 over.setGState(gstate);
253 over.setColorFill(Color.LIGHT_GRAY);
254 over.showTextAligned(Element.ALIGN_CENTER, watermarkText, (pageSize.width() / 2), (pageSize.height() / 2), 45);
255 over.endText();
256 i++;
257 }
258 pdfStamper.close();
259 }
260 catch (DocumentException ex) {
261 throw new IOException("iText error creating watermark on PDF", ex);
262 }
263 catch (IOException ex) {
264 throw new IOException("IO error creating watermark on PDF", ex);
265 }
266 return outputStream.toByteArray();
267 }
268
269
270
271
272
273
274
275
276 private static String replaceValuesIteratingThroughFile(String template, Map<String, String> replacementList) {
277 StringBuilder buffOriginal = new StringBuilder();
278 StringBuilder buffNormalized = new StringBuilder();
279
280 String[] keys = template.split("[\\s]+");
281
282
283 for (String key : keys) {
284 if (validListTagFound(key)) {
285 String replacementKey = key.substring(1);
286 String value = replacementList.get(replacementKey);
287 if (ObjectUtils.isNotNull(value)) {
288 buffOriginal.append(value + " ");
289 }
290 else {
291 buffOriginal.append(" ");
292 }
293 }
294 else {
295 buffOriginal.append(key + " ");
296 }
297 }
298 return buffOriginal.toString();
299 }
300 }