@@ -62,6 +62,10 @@ public class PdfExporter extends AbstractFormatExporter {
6262 private static final int DEFAULT_COLUMN_WIDTH = 150 ;
6363 private static final String KN_EXPORT_EXTRA_FIELD_LABEL = "kn-export-extra-field-label" ;
6464 private static final String KN_EXPORT_EXTRA_FIELD_VALUE = "kn-export-extra-field-value" ;
65+ private static final float HEADER_FONT_SIZE = 10f ;
66+ private static final float HEADER_LEADING = 12f ;
67+ private static final float HEADER_SIDE_MARGIN = 20f ;
68+ private static final float HEADER_BOTTOM_GAP = 10f ;
6569
6670
6771 private float totalColumnsWidth = 0 ;
@@ -131,12 +135,23 @@ private void exportTableWidget(PDDocument document, String templateString, long
131135 JSONArray jsonArray ;
132136 URL resource = getClass ().getClassLoader ().getResource ("/fonts/DejaVuSans.ttf" );
133137 File pdfFontFile = new File (resource .toURI ());
138+ String extraValueLabel = null ;
139+ String extraValue = null ;
140+ if (variables != null && variables .length () > 0 ) {
141+ extraValueLabel = variables .optString (KN_EXPORT_EXTRA_FIELD_LABEL );
142+ extraValue = variables .optString (KN_EXPORT_EXTRA_FIELD_VALUE );
143+ }
144+ float reservedTopHeight = calculateReservedTopHeightForDocumentInfo (extraValueLabel , extraValue );
134145 do {
135146 dataStore = this .getDataStoreForWidget (template , widget , offset , fetchSize );
136147
148+ if (offset == 0 ) {
149+ totalNumberOfRows = dataStore .getInt ("results" );
150+ }
151+
137152 PDPage newPage = createPage (settings , widget );
138153 document .addPage (newPage );
139- table = createBaseTable (document , newPage );
154+ table = createBaseTable (document , newPage , reservedTopHeight );
140155
141156 JSONObject widgetData = dataStore .getJSONObject ("widgetData" );
142157 JSONObject widgetContent = widgetData .getJSONObject ("content" );
@@ -159,23 +174,14 @@ private void exportTableWidget(PDDocument document, String templateString, long
159174 columnStyles = getColumnsStyles (columnsOrdered , widgetContent );
160175 initColumnWidths (columnStyles , columnsOrdered .length (), pdfHiddenColumns );
161176
162- totalNumberOfRows = dataStore .getInt ("results" );
163-
164177 }
165178
166179 rows = dataStore .getJSONArray ("rows" );
167180
168181 PDFont font = PDType0Font .load (table .document , pdfFontFile );
169182
170- String extraValueLabel = null ;
171- String extraValue = null ;
172- if (variables != null && variables .length () > 0 ) {
173- extraValueLabel = variables .optString (KN_EXPORT_EXTRA_FIELD_LABEL );
174- extraValue = variables .optString (KN_EXPORT_EXTRA_FIELD_VALUE );
175- }
176-
177183 addDataToTable (table , settings , columnsOrdered , pdfHiddenColumns , columnDateFormats , columnStyles ,
178- rows , font , style , widgetData , widgetContent , creationUser , extraValueLabel , extraValue );
184+ rows , font , style , widgetData , widgetContent , creationUser , totalNumberOfRows , extraValueLabel , extraValue );
179185
180186 offset += fetchSize ;
181187
@@ -194,10 +200,10 @@ private void exportTableWidget(PDDocument document, String templateString, long
194200 }
195201
196202 private void addDataToTable (BaseTable table , JSONObject settings , JSONArray columnsOrdered ,
197- List <Integer > pdfHiddenColumns , String [] columnDateFormats , JSONObject [] columnStyles , JSONArray rows , PDFont font , JSONObject style , JSONObject widgetData , JSONObject widgetContent , String creationUser , String extraValueLabel , String extraValue )
203+ List <Integer > pdfHiddenColumns , String [] columnDateFormats , JSONObject [] columnStyles , JSONArray rows , PDFont font , JSONObject style , JSONObject widgetData , JSONObject widgetContent , String creationUser , int totalNumberOfRows , String extraValueLabel , String extraValue )
198204 throws JSONException {
199205
200- addHeaderToTable (table , style , widgetData , widgetContent , columnsOrdered , pdfHiddenColumns , font , creationUser , extraValueLabel , extraValue );
206+ addHeaderToTable (table , style , widgetData , widgetContent , columnsOrdered , pdfHiddenColumns , font , creationUser , totalNumberOfRows , extraValueLabel , extraValue );
201207
202208 // Check if summary row is enabled
203209 boolean summaryRowEnabled = false ;
@@ -307,11 +313,11 @@ private void addDataToTable(BaseTable table, JSONObject settings, JSONArray colu
307313 }
308314
309315 private void addHeaderToTable (BaseTable table , JSONObject style , JSONObject widgetData , JSONObject widgetContent ,
310- JSONArray columnsOrdered , List <Integer > pdfHiddenColumns , PDFont font , String creationUser , String extraValueLabel , String extraValueField ) throws JSONException {
316+ JSONArray columnsOrdered , List <Integer > pdfHiddenColumns , PDFont font , String creationUser , int totalNumberOfRows , String extraValueLabel , String extraValueField ) throws JSONException {
311317 JSONArray groupsFromWidgetContent = getGroupsFromWidgetContent (widgetData );
312318 Map <String , String > groupsAndColumnsMap = getGroupAndColumnsMap (widgetContent , groupsFromWidgetContent );
313319
314- createDocumentInformationRow (table , font , creationUser , extraValueLabel , extraValueField );
320+ createDocumentInformationRow (table , font , creationUser , totalNumberOfRows , extraValueLabel , extraValueField );
315321
316322 if (!groupsAndColumnsMap .isEmpty ()) {
317323 Row <PDPage > groupHeaderRow = table .createRow (15f );
@@ -736,20 +742,24 @@ private static String extractParameterName(String parameterKey) {
736742 return parameterKey ;
737743 }
738744
739- private void createDocumentInformationRow (BaseTable table , PDFont font , String creationUser , String extraValueLabel , String extraValue ) {
745+ private void createDocumentInformationRow (BaseTable table , PDFont font , String creationUser , int totalNumberOfRows , String extraValueLabel , String extraValue ) {
740746 try {
741747 String executionDateLabel ;
742748 String creationUserLabel ;
749+ String totalRecordsLabel ;
743750
744751 if (getLocale ().toString ().equals ("sk_SK" )) {
745752 executionDateLabel = "Dátum vytvorenia: " ;
746753 creationUserLabel = "Vytvoril: " ;
754+ totalRecordsLabel = "Celkový počet záznamov: " ;
747755 } else if (getLocale ().toString ().equals ("it_IT" )) {
748756 executionDateLabel = "Data di esecuzione: " ;
749757 creationUserLabel = "Utente di esecuzione: " ;
758+ totalRecordsLabel = "Numero totale di record: " ;
750759 } else {
751760 executionDateLabel = "Execution User: " ;
752761 creationUserLabel = "Creation User: " ;
762+ totalRecordsLabel = "Total Records: " ;
753763 }
754764
755765 PDPage page = table .getCurrentPage ();
@@ -758,33 +768,30 @@ private void createDocumentInformationRow(BaseTable table, PDFont font, String c
758768
759769 String line1 = executionDateLabel + executionDate ;
760770 String line2 = creationUserLabel + creationUser ;
761- String line3 = null ;
762- if (extraValueLabel != null && !extraValueLabel .isEmpty () && extraValue != null && !extraValue .isEmpty ()) {
763- line3 = extraValueLabel + ": " + extraValue ;
764- }
771+ String line3 = totalRecordsLabel + totalNumberOfRows ;
772+ boolean isExtraValuePresent = extraValueLabel != null && !extraValueLabel .isEmpty () && extraValue != null && !extraValue .isEmpty ();
773+ String line4 = isExtraValuePresent ? extraValueLabel + ": " + extraValue : null ;
765774
766- float fontSize = 10f ;
767- float leading = 12f ;
768- float margin = 20f ;
775+ float fontSize = HEADER_FONT_SIZE ;
776+ float leading = HEADER_LEADING ;
769777
770778 float pageWidth = page .getMediaBox ().getWidth ();
771- float pageHeight = page .getMediaBox ().getHeight ();
772-
773- float w1 = font .getStringWidth (line1 ) / 1000f * fontSize ;
774- float w2 = font .getStringWidth (line2 ) / 1000f * fontSize ;
775- float w3 ;
776- if (line3 != null ) {
777- w3 = font .getStringWidth (line3 ) / 1000f * fontSize ;
778- w2 = Math .max (w2 , w3 );
779+ List <String > headerLines = new ArrayList <>();
780+ headerLines .add (line1 );
781+ headerLines .add (line2 );
782+ headerLines .add (line3 );
783+ if (isExtraValuePresent ) {
784+ headerLines .add (line4 );
779785 }
780- float maxW = Math .max (w1 , w2 );
781786
782- float x = pageWidth - margin - maxW ;
787+ float maxW = 0f ;
788+ for (String headerLine : headerLines ) {
789+ maxW = Math .max (maxW , font .getStringWidth (headerLine ) / 1000f * fontSize );
790+ }
783791
784- float yStartNewPage = pageHeight - ( 2 * margin ) ;
792+ float x = pageWidth - HEADER_SIDE_MARGIN - maxW ;
785793
786- float additionalGap = 12f ;
787- float y = yStartNewPage + additionalGap + leading ;
794+ float y = getHeaderStartY (page );
788795
789796 try (org .apache .pdfbox .pdmodel .PDPageContentStream contentStream =
790797 new org .apache .pdfbox .pdmodel .PDPageContentStream (table .document , page , org .apache .pdfbox .pdmodel .PDPageContentStream .AppendMode .APPEND , true )) {
@@ -793,12 +800,11 @@ private void createDocumentInformationRow(BaseTable table, PDFont font, String c
793800 contentStream .setFont (font , fontSize );
794801 contentStream .setNonStrokingColor (Color .BLACK );
795802 contentStream .newLineAtOffset (x , y );
796- contentStream .showText (line1 );
797- contentStream .newLineAtOffset (0 , -leading );
798- contentStream .showText (line2 );
799- if (line3 != null ) {
800- contentStream .newLineAtOffset (0 , -leading );
801- contentStream .showText (line3 );
803+ for (int i = 0 ; i < headerLines .size (); i ++) {
804+ if (i > 0 ) {
805+ contentStream .newLineAtOffset (0 , -leading );
806+ }
807+ contentStream .showText (headerLines .get (i ));
802808 }
803809 contentStream .endText ();
804810
@@ -808,6 +814,15 @@ private void createDocumentInformationRow(BaseTable table, PDFont font, String c
808814 }
809815 }
810816
817+ private float calculateReservedTopHeightForDocumentInfo (String extraValueLabel , String extraValue ) {
818+ int documentInfoLines = (extraValueLabel != null && !extraValueLabel .isEmpty () && extraValue != null && !extraValue .isEmpty ()) ? 4 : 3 ;
819+ return (documentInfoLines * HEADER_LEADING ) + HEADER_BOTTOM_GAP ;
820+ }
821+
822+ private float getHeaderStartY (PDPage page ) {
823+ return page .getMediaBox ().getHeight () - HEADER_SIDE_MARGIN + 4f ;
824+ }
825+
811826 private int getAdjacentEqualNamesAmount (Map <String , String > groupsAndColumnsMap , JSONArray columnsOrdered , int matchStartIndex , String groupNameToMatch ) {
812827 try {
813828 int adjacents = 0 ;
@@ -1071,7 +1086,7 @@ private PDRectangle calculateTableDimensions(JSONObject widgetConf) {
10711086 }
10721087 }
10731088
1074- private BaseTable createBaseTable (PDDocument doc , PDPage page ) {
1089+ private BaseTable createBaseTable (PDDocument doc , PDPage page , float reservedTopHeight ) {
10751090 try {
10761091 float margin = 20 ;
10771092 // starting y position is whole page height subtracted by top and bottom margin
@@ -1080,7 +1095,8 @@ private BaseTable createBaseTable(PDDocument doc, PDPage page) {
10801095 float tableWidth = page .getMediaBox ().getWidth () - (2 * margin );
10811096 // y position is your coordinate of top left corner of the table
10821097 Assert .assertTrue (tableWidth > 0 , "Page dimension is too small!" );
1083- float yPosition = 550 ;
1098+ float computedYPosition = Math .min (550 , getHeaderStartY (page ) - reservedTopHeight );
1099+ float yPosition = Math .max (bottomMargin + HEADER_BOTTOM_GAP , computedYPosition );
10841100 return new BaseTable (yPosition , yStartNewPage , bottomMargin , tableWidth , margin , doc , page , true , true );
10851101 } catch (Exception e ) {
10861102 throw new SpagoBIRuntimeException ("Cannot create PDF Base Table object:" , e );
0 commit comments