Skip to content

Commit 2d97c6a

Browse files
Pages placeholder (#933)
* Replace {{pages}} placeholder with document page count Issue:201569 * Change inline imports for top of file imports * Turn {{pages}} placeholder into a constant * Adhere to constants naming and declaration conventions (cherry picked from commit 4261da2)
1 parent d3a9ea3 commit 2d97c6a

File tree

1 file changed

+82
-3
lines changed

1 file changed

+82
-3
lines changed

java/src/main/java/com/genexus/reports/PDFReportPDFBox.java

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
3535
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
3636
import org.apache.pdfbox.pdmodel.interactive.viewerpreferences.PDViewerPreferences;
37+
import org.apache.pdfbox.text.PDFTextStripper;
38+
import org.apache.pdfbox.text.TextPosition;
3739
import org.apache.pdfbox.util.Matrix;
3840

3941
import org.jsoup.Jsoup;
@@ -65,6 +67,8 @@ public class PDFReportPDFBox extends GXReportPDFCommons{
6567
private final float DEFAULT_PDFBOX_LEADING = 1.2f;
6668

6769
private Set<String> supportedHTMLTags = new HashSet<>();
70+
private PDPageContentStream currentPageContentStream;
71+
private final static String PAGES_PLACEHOLDER = "{{pages}}";
6872

6973
static {
7074
log = org.apache.logging.log4j.LogManager.getLogger(PDFReportPDFBox.class);
@@ -811,7 +815,8 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
811815
contentStream.close();
812816
}
813817

814-
if(sTxt.trim().equalsIgnoreCase("{{Pages}}")) {
818+
// Handle {{Pages}}
819+
if (sTxt.trim().equalsIgnoreCase(PAGES_PLACEHOLDER)) {
815820
if (!templateCreated) {
816821
templateFont = baseFont;
817822
templateFontSize = fontSize;
@@ -820,7 +825,7 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
820825
templateY = this.pageSize.getUpperRightY() - bottomAux - topMargin - bottomMargin;
821826
templateCreated = true;
822827
}
823-
sTxt = String.valueOf(this.page);
828+
sTxt = PAGES_PLACEHOLDER;
824829
}
825830

826831
float textBlockWidth = rightAux - leftAux;
@@ -1227,12 +1232,86 @@ else if (length == 15840 && width == 12240)
12271232
return new PDRectangle((int)(width / PAGE_SCALE_X) + leftMargin, (int)(length / PAGE_SCALE_Y) + topMargin);
12281233
}
12291234

1235+
private void replaceTemplatePages() throws IOException {
1236+
int totalPages = document.getNumberOfPages();
1237+
for (int i = 0; i < totalPages; i++) {
1238+
final PDPage page = document.getPage(i);
1239+
final List<float[]> replacements = new java.util.ArrayList<>();
1240+
PDFTextStripper stripper = new PDFTextStripper() {
1241+
@Override
1242+
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
1243+
String placeholder = PAGES_PLACEHOLDER;
1244+
int index = text.indexOf(placeholder);
1245+
while (index != -1 && index + placeholder.length() <= textPositions.size()) {
1246+
float minX = Float.MAX_VALUE;
1247+
float maxX = 0;
1248+
float minY = Float.MAX_VALUE;
1249+
float maxY = 0;
1250+
for (int j = index; j < index + placeholder.length(); j++) {
1251+
TextPosition tp = textPositions.get(j);
1252+
float tpX = tp.getXDirAdj();
1253+
float tpY = tp.getYDirAdj();
1254+
float tpWidth = tp.getWidthDirAdj();
1255+
float tpHeight = tp.getHeightDir();
1256+
if (tpX < minX) {
1257+
minX = tpX;
1258+
}
1259+
if (tpX + tpWidth > maxX) {
1260+
maxX = tpX + tpWidth;
1261+
}
1262+
if (tpY < minY) {
1263+
minY = tpY;
1264+
}
1265+
if (tpY + tpHeight > maxY) {
1266+
maxY = tpY + tpHeight;
1267+
}
1268+
}
1269+
float bboxWidth = maxX - minX;
1270+
float bboxHeight = maxY - minY;
1271+
float origBoxBottom = pageSize.getHeight() - maxY;
1272+
float originalCenterX = minX + bboxWidth / 2;
1273+
float originalCenterY = origBoxBottom + bboxHeight / 2;
1274+
float newCenterY = originalCenterY + (bboxHeight * 0.5f);
1275+
float enlargedWidth = bboxWidth * 2.5f;
1276+
float enlargedHeight = bboxHeight * 2.5f;
1277+
float rectX = originalCenterX - (enlargedWidth / 2);
1278+
float rectY = newCenterY - (enlargedHeight / 2);
1279+
float baselineY = newCenterY;
1280+
replacements.add(new float[] { rectX, rectY, enlargedWidth, enlargedHeight, baselineY });
1281+
index = text.indexOf(placeholder, index + placeholder.length());
1282+
}
1283+
super.writeString(text, textPositions);
1284+
}
1285+
};
1286+
stripper.setStartPage(i + 1);
1287+
stripper.setEndPage(i + 1);
1288+
stripper.getText(document);
1289+
if (!replacements.isEmpty()) {
1290+
try (PDPageContentStream cs = new PDPageContentStream(
1291+
document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
1292+
for (float[] rep : replacements) {
1293+
cs.addRect(rep[0], rep[1], rep[2], rep[3]);
1294+
cs.setNonStrokingColor(java.awt.Color.WHITE);
1295+
cs.fill();
1296+
cs.beginText();
1297+
cs.setFont(templateFont, templateFontSize);
1298+
cs.setNonStrokingColor(templateColorFill);
1299+
cs.newLineAtOffset(rep[0], rep[4]);
1300+
cs.showText(String.valueOf(totalPages));
1301+
cs.endText();
1302+
}
1303+
}
1304+
}
1305+
}
1306+
}
1307+
12301308
public void GxEndDocument() {
12311309
try {
12321310
if(document.getNumberOfPages() == 0) {
12331311
document.addPage(new PDPage(this.pageSize));
12341312
pages++;
12351313
}
1314+
replaceTemplatePages();
12361315
int copies = 1;
12371316
try {
12381317
copies = Integer.parseInt(printerSettings.getProperty(form, Const.COPIES));
@@ -1351,4 +1430,4 @@ public void GxStartPage() {
13511430
page = page + 1;
13521431
}
13531432

1354-
}
1433+
}

0 commit comments

Comments
 (0)