29
29
import org .apache .pdfbox .pdmodel .graphics .state .RenderingMode ;
30
30
import org .apache .pdfbox .pdmodel .interactive .action .PDActionJavaScript ;
31
31
import org .apache .pdfbox .pdmodel .interactive .viewerpreferences .PDViewerPreferences ;
32
+ import org .apache .pdfbox .text .PDFTextStripper ;
33
+ import org .apache .pdfbox .text .TextPosition ;
32
34
import org .apache .pdfbox .util .Matrix ;
33
35
34
36
import org .jsoup .Jsoup ;
@@ -59,6 +61,7 @@ public class PDFReportPDFBox extends GXReportPDFCommons{
59
61
private final float DEFAULT_PDFBOX_LEADING = 1.2f ;
60
62
private Set <String > supportedHTMLTags = new HashSet <>();
61
63
private PDPageContentStream currentPageContentStream ;
64
+ private final static String PAGES_PLACEHOLDER = "{{pages}}" ;
62
65
63
66
static {
64
67
log = org .apache .logging .log4j .LogManager .getLogger (PDFReportPDFBox .class );
@@ -852,7 +855,7 @@ else if (barcodeType != null) {
852
855
}
853
856
854
857
// Handle {{Pages}}
855
- if (sTxt .trim ().equalsIgnoreCase ("{{Pages}}" )) {
858
+ if (sTxt .trim ().equalsIgnoreCase (PAGES_PLACEHOLDER )) {
856
859
if (!templateCreated ) {
857
860
templateFont = baseFont ;
858
861
templateFontSize = fontSize ;
@@ -861,7 +864,7 @@ else if (barcodeType != null) {
861
864
templateY = this .pageSize .getUpperRightY () - bottomAux - topMargin - bottomMargin ;
862
865
templateCreated = true ;
863
866
}
864
- sTxt = String . valueOf ( this . page ) ;
867
+ sTxt = PAGES_PLACEHOLDER ;
865
868
}
866
869
867
870
float textBlockWidth = rightAux - leftAux ;
@@ -1265,12 +1268,86 @@ else if (length == 15840 && width == 12240)
1265
1268
return new PDRectangle ((int )(width / PAGE_SCALE_X ) + leftMargin , (int )(length / PAGE_SCALE_Y ) + topMargin );
1266
1269
}
1267
1270
1271
+ private void replaceTemplatePages () throws IOException {
1272
+ int totalPages = document .getNumberOfPages ();
1273
+ for (int i = 0 ; i < totalPages ; i ++) {
1274
+ final PDPage page = document .getPage (i );
1275
+ final List <float []> replacements = new java .util .ArrayList <>();
1276
+ PDFTextStripper stripper = new PDFTextStripper () {
1277
+ @ Override
1278
+ protected void writeString (String text , List <TextPosition > textPositions ) throws IOException {
1279
+ String placeholder = PAGES_PLACEHOLDER ;
1280
+ int index = text .indexOf (placeholder );
1281
+ while (index != -1 && index + placeholder .length () <= textPositions .size ()) {
1282
+ float minX = Float .MAX_VALUE ;
1283
+ float maxX = 0 ;
1284
+ float minY = Float .MAX_VALUE ;
1285
+ float maxY = 0 ;
1286
+ for (int j = index ; j < index + placeholder .length (); j ++) {
1287
+ TextPosition tp = textPositions .get (j );
1288
+ float tpX = tp .getXDirAdj ();
1289
+ float tpY = tp .getYDirAdj ();
1290
+ float tpWidth = tp .getWidthDirAdj ();
1291
+ float tpHeight = tp .getHeightDir ();
1292
+ if (tpX < minX ) {
1293
+ minX = tpX ;
1294
+ }
1295
+ if (tpX + tpWidth > maxX ) {
1296
+ maxX = tpX + tpWidth ;
1297
+ }
1298
+ if (tpY < minY ) {
1299
+ minY = tpY ;
1300
+ }
1301
+ if (tpY + tpHeight > maxY ) {
1302
+ maxY = tpY + tpHeight ;
1303
+ }
1304
+ }
1305
+ float bboxWidth = maxX - minX ;
1306
+ float bboxHeight = maxY - minY ;
1307
+ float origBoxBottom = pageSize .getHeight () - maxY ;
1308
+ float originalCenterX = minX + bboxWidth / 2 ;
1309
+ float originalCenterY = origBoxBottom + bboxHeight / 2 ;
1310
+ float newCenterY = originalCenterY + (bboxHeight * 0.5f );
1311
+ float enlargedWidth = bboxWidth * 2.5f ;
1312
+ float enlargedHeight = bboxHeight * 2.5f ;
1313
+ float rectX = originalCenterX - (enlargedWidth / 2 );
1314
+ float rectY = newCenterY - (enlargedHeight / 2 );
1315
+ float baselineY = newCenterY ;
1316
+ replacements .add (new float [] { rectX , rectY , enlargedWidth , enlargedHeight , baselineY });
1317
+ index = text .indexOf (placeholder , index + placeholder .length ());
1318
+ }
1319
+ super .writeString (text , textPositions );
1320
+ }
1321
+ };
1322
+ stripper .setStartPage (i + 1 );
1323
+ stripper .setEndPage (i + 1 );
1324
+ stripper .getText (document );
1325
+ if (!replacements .isEmpty ()) {
1326
+ try (PDPageContentStream cs = new PDPageContentStream (
1327
+ document , page , PDPageContentStream .AppendMode .APPEND , true , true )) {
1328
+ for (float [] rep : replacements ) {
1329
+ cs .addRect (rep [0 ], rep [1 ], rep [2 ], rep [3 ]);
1330
+ cs .setNonStrokingColor (java .awt .Color .WHITE );
1331
+ cs .fill ();
1332
+ cs .beginText ();
1333
+ cs .setFont (templateFont , templateFontSize );
1334
+ cs .setNonStrokingColor (templateColorFill );
1335
+ cs .newLineAtOffset (rep [0 ], rep [4 ]);
1336
+ cs .showText (String .valueOf (totalPages ));
1337
+ cs .endText ();
1338
+ }
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+
1268
1344
public void GxEndDocument () {
1269
1345
try {
1270
1346
if (document .getNumberOfPages () == 0 ) {
1271
1347
document .addPage (new PDPage (this .pageSize ));
1272
1348
pages ++;
1273
1349
}
1350
+ replaceTemplatePages ();
1274
1351
int copies = 1 ;
1275
1352
try {
1276
1353
copies = Integer .parseInt (printerSettings .getProperty (form , Const .COPIES ));
@@ -1407,4 +1484,4 @@ public void GxEndPage() {
1407
1484
}
1408
1485
}
1409
1486
1410
- }
1487
+ }
0 commit comments