2929import org .apache .pdfbox .pdmodel .graphics .state .RenderingMode ;
3030import org .apache .pdfbox .pdmodel .interactive .action .PDActionJavaScript ;
3131import org .apache .pdfbox .pdmodel .interactive .viewerpreferences .PDViewerPreferences ;
32+ import org .apache .pdfbox .text .PDFTextStripper ;
33+ import org .apache .pdfbox .text .TextPosition ;
3234import org .apache .pdfbox .util .Matrix ;
3335
3436import org .jsoup .Jsoup ;
@@ -59,6 +61,7 @@ public class PDFReportPDFBox extends GXReportPDFCommons{
5961 private final float DEFAULT_PDFBOX_LEADING = 1.2f ;
6062 private Set <String > supportedHTMLTags = new HashSet <>();
6163 private PDPageContentStream currentPageContentStream ;
64+ private final static String PAGES_PLACEHOLDER = "{{pages}}" ;
6265
6366 static {
6467 log = org .apache .logging .log4j .LogManager .getLogger (PDFReportPDFBox .class );
@@ -852,7 +855,7 @@ else if (barcodeType != null) {
852855 }
853856
854857 // Handle {{Pages}}
855- if (sTxt .trim ().equalsIgnoreCase ("{{Pages}}" )) {
858+ if (sTxt .trim ().equalsIgnoreCase (PAGES_PLACEHOLDER )) {
856859 if (!templateCreated ) {
857860 templateFont = baseFont ;
858861 templateFontSize = fontSize ;
@@ -861,7 +864,7 @@ else if (barcodeType != null) {
861864 templateY = this .pageSize .getUpperRightY () - bottomAux - topMargin - bottomMargin ;
862865 templateCreated = true ;
863866 }
864- sTxt = String . valueOf ( this . page ) ;
867+ sTxt = PAGES_PLACEHOLDER ;
865868 }
866869
867870 float textBlockWidth = rightAux - leftAux ;
@@ -1265,12 +1268,86 @@ else if (length == 15840 && width == 12240)
12651268 return new PDRectangle ((int )(width / PAGE_SCALE_X ) + leftMargin , (int )(length / PAGE_SCALE_Y ) + topMargin );
12661269 }
12671270
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+
12681344 public void GxEndDocument () {
12691345 try {
12701346 if (document .getNumberOfPages () == 0 ) {
12711347 document .addPage (new PDPage (this .pageSize ));
12721348 pages ++;
12731349 }
1350+ replaceTemplatePages ();
12741351 int copies = 1 ;
12751352 try {
12761353 copies = Integer .parseInt (printerSettings .getProperty (form , Const .COPIES ));
@@ -1407,4 +1484,4 @@ public void GxEndPage() {
14071484 }
14081485 }
14091486
1410- }
1487+ }
0 commit comments