@@ -284,7 +284,7 @@ private void styleHeaderCell(JSONObject settings, Cell<PDPage> headerCell, PDFon
284284 JSONObject styleJSONObject = getJsonObjectUtils ().getStyleFromSettings (settings );
285285 if (settings != null && settings .has ("style" ) && styleJSONObject .has ("headers" )) {
286286 Style style = getStyleCustomObjFromProps (null , styleJSONObject .getJSONObject ("headers" ), "" );
287- headerCell .setFont (font );
287+ headerCell .setFont (getFontForStyle ( style , font ) );
288288 headerCell .setFontSize (Float .parseFloat (style .getFontSize ().replace ("px" , "" )));
289289 Color headerBackground = parseJavaColor (style .getBackgroundColor ());
290290 if (headerBackground != null && !isRgbColor (headerBackground , COLOR_WHITE_COMPONENT , COLOR_WHITE_COMPONENT , COLOR_WHITE_COMPONENT )) {
@@ -363,9 +363,8 @@ private void createFiltersInformationRow(BaseTable table, PDFont font, JSONArray
363363 float margin = HEADER_SIDE_MARGIN ;
364364 float fontSize = HEADER_FONT_SIZE ;
365365 float leading = HEADER_LEADING ;
366- float indent = margin + 10f ;
367366 PDPage page = footerCurrentPage != null ? footerCurrentPage : document .getPage (document .getNumberOfPages () - 1 );
368- float maxTextWidth = ( page .getMediaBox ().getWidth () / 2f ) - indent ;
367+ float maxTextWidth = page .getMediaBox ().getWidth () - ( 2 * margin ) ;
369368 String filtersLabel = getFiltersLabel ();
370369 float currentY = footerCurrentY ;
371370 float pageTopStart = page .getMediaBox ().getHeight () - margin - leading ;
@@ -374,6 +373,9 @@ private void createFiltersInformationRow(BaseTable table, PDFont font, JSONArray
374373 currentY = getFooterStartYFromTable (table , leading );
375374 }
376375
376+ // Add space between selections and filters
377+ currentY -= leading ;
378+
377379 if (currentY <= bottomLimit ) {
378380 page = new PDPage (page .getMediaBox ());
379381 document .addPage (page );
@@ -391,10 +393,23 @@ private void createFiltersInformationRow(BaseTable table, PDFont font, JSONArray
391393 }
392394
393395 for (String filter : filters ) {
394- List <String > wrapped = wrapText (font , fontSize , filter , maxTextWidth );
395- List <String > linesToPrint = wrapped .isEmpty () ? Collections .singletonList (filter ) : wrapped ;
396+ // Split filter by ": " to separate key and value
397+ String [] parts = filter .split (": " , 2 );
398+ String key = parts .length > 0 ? parts [0 ] : "" ;
399+ String value = parts .length > 1 ? parts [1 ] : "" ;
400+
401+ // Calculate key width for underlining
402+ float keyWidth = font .getStringWidth (key ) / 1000f * fontSize ;
403+
404+ // Wrap value if needed
405+ float colonWidth = font .getStringWidth (": " ) / 1000f * fontSize ;
406+ float valuesX = margin + keyWidth + colonWidth ;
407+ float maxValueWidth = maxTextWidth - keyWidth - colonWidth ;
396408
397- for (String line : linesToPrint ) {
409+ List <String > wrappedValues = maxValueWidth > 0 ? wrapText (font , fontSize , value , maxValueWidth ) : Collections .singletonList (value );
410+ List <String > linesToPrint = wrappedValues .isEmpty () ? Collections .singletonList (value ) : wrappedValues ;
411+
412+ for (int i = 0 ; i < linesToPrint .size (); i ++) {
398413 if (currentY <= bottomLimit ) {
399414 page = new PDPage (page .getMediaBox ());
400415 document .addPage (page );
@@ -404,10 +419,38 @@ private void createFiltersInformationRow(BaseTable table, PDFont font, JSONArray
404419 try (PDPageContentStream cs = new PDPageContentStream (document , page , PDPageContentStream .AppendMode .APPEND , true )) {
405420 cs .setNonStrokingColor (Color .BLACK );
406421 cs .setFont (font , fontSize );
407- cs .beginText ();
408- cs .newLineAtOffset (indent , currentY );
409- cs .showText (line );
410- cs .endText ();
422+
423+ if (i == 0 ) {
424+ // First line: render key with underline, colon, and value
425+ cs .beginText ();
426+ cs .newLineAtOffset (margin , currentY );
427+ cs .showText (key );
428+ cs .endText ();
429+
430+ // Draw underline under key
431+ float underlineY = currentY - 2.0f ;
432+ cs .setLineWidth (0.5f );
433+ cs .moveTo (margin , underlineY );
434+ cs .lineTo (margin + keyWidth , underlineY );
435+ cs .stroke ();
436+
437+ // Render colon and value
438+ cs .beginText ();
439+ cs .newLineAtOffset (margin + keyWidth , currentY );
440+ cs .showText (": " );
441+ cs .endText ();
442+
443+ cs .beginText ();
444+ cs .newLineAtOffset (valuesX , currentY );
445+ cs .showText (linesToPrint .get (i ));
446+ cs .endText ();
447+ } else {
448+ // Continuation lines: just render the value
449+ cs .beginText ();
450+ cs .newLineAtOffset (valuesX , currentY );
451+ cs .showText (linesToPrint .get (i ));
452+ cs .endText ();
453+ }
411454 }
412455 currentY -= leading ;
413456 }
@@ -1093,10 +1136,36 @@ private void applyStyleToCell(Style style, Cell<PDPage> cell, String type) {
10931136 cell .setTextColor (textColor );
10941137 }
10951138
1139+ // Boxable does not expose a font-weight flag, so switch to a bold/italic font when requested.
1140+ cell .setFont (getFontForStyle (style , PDType1Font .HELVETICA ));
1141+
10961142 cell .setAlign (getHorizontalAlignmentFromStyle (style , type ));
10971143 cell .setValign (getVerticalAlignmentFromStyle (style ));
10981144 }
10991145
1146+ private boolean isBoldFontWeight (Style style ) {
1147+ return style != null && !stringIsEmpty (style .getFontWeight ()) && "bold" .equalsIgnoreCase (style .getFontWeight ());
1148+ }
1149+
1150+ private boolean isItalicFontStyle (Style style ) {
1151+ return style != null && !stringIsEmpty (style .getFontStyle ()) && "italic" .equalsIgnoreCase (style .getFontStyle ());
1152+ }
1153+
1154+ private PDFont getFontForStyle (Style style , PDFont defaultFont ) {
1155+ boolean isBold = isBoldFontWeight (style );
1156+ boolean isItalic = isItalicFontStyle (style );
1157+
1158+ if (isBold && isItalic ) {
1159+ return PDType1Font .HELVETICA_BOLD_OBLIQUE ;
1160+ } else if (isBold ) {
1161+ return PDType1Font .HELVETICA_BOLD ;
1162+ } else if (isItalic ) {
1163+ return PDType1Font .HELVETICA_OBLIQUE ;
1164+ }
1165+
1166+ return defaultFont ;
1167+ }
1168+
11001169
11011170 private Style getCellStyleByStyleKey (String styleKey , Map <String , Style > columnsCellStyles , JSONObject theRightStyle , String defaultRowBackgroundColor ) {
11021171 Style cellStyle ;
@@ -1171,7 +1240,7 @@ private BaseTable createBaseTable(PDDocument doc, PDPage page, int reservedSelec
11711240 float yStartNewPage = page .getMediaBox ().getHeight () - (2 * margin );
11721241 float baseBottomMargin = 20 ;
11731242 float leading = 12f ;
1174- float extraGapFromTable = 6f ; // gap between table and selections
1243+ float extraGapFromTable = 20f ; // gap between table and selections
11751244
11761245 float bottomMargin = baseBottomMargin + reservedSelectionLines * leading + extraGapFromTable ;
11771246 float tableWidth = page .getMediaBox ().getWidth () - (2 * margin );
0 commit comments