Updated code for pdf correction

This commit is contained in:
nisha
2024-10-25 01:53:50 +05:30
parent c688b8a1c5
commit b057984964
2 changed files with 205 additions and 248 deletions

View File

@@ -10,11 +10,15 @@ import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest;
import net.gepafin.tendermanagement.model.response.*;
import net.gepafin.tendermanagement.service.CallService;
import net.gepafin.tendermanagement.util.Utils;
import net.gepafin.tendermanagement.util.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
//import com.itextpdf.layout.element.
@@ -37,6 +41,7 @@ public class PdfDao {
@Autowired
private Validator validator;
public static final Logger log = LoggerFactory.getLogger(PdfDao.class);
public byte[] generatePdf(HttpServletRequest request,Long applicationId) {
try {
@@ -79,16 +84,7 @@ public class PdfDao {
for(FormApplicationResponse formApplicationResponse: applicationGetResponseBean.getForm()) {
document.add(new Paragraph(formApplicationResponse.getLabel(),sectionFont));
document.add(new Paragraph(" ")); // Add line break
List<FieldLabelValuePairRequest> fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse);
for (FieldLabelValuePairRequest pair : fieldLabelValuePairRequests) {
String label = pair.getLabel();
Object value = pair.getValue();
Integer pages=0;
pages=addLabelValuePair(writer,document, label, value, labelFont,valueFont,call.getName(),pages);
if(pages !=0 ){
// pageEvent.setTotalPages(writer.getPageNumber());
}
}
List<FieldLabelValuePairRequest> fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse,writer,document);
addColoredLines(writer,document,greenColor);
document.add(new Paragraph(" ")); // Add line break
}
@@ -164,15 +160,6 @@ public class PdfDao {
addColoredLines(writer,document,greenColor);
// System.out.println(writer.getPageSize());
// System.out.println(document.getPageSize());
// System.out.println(document.getPageNumber());
// System.out.println(writer.getPageNumber());
// document.setPageCount(100);
// document.setPageCount(writer.getPageNumber());
// System.out.println(document.getPageNumber());
// Close the document
document.close();
// Convert to byte array for response
@@ -185,12 +172,13 @@ public class PdfDao {
return null;
}
private Integer addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,String title,Integer totalPages) throws DocumentException {
private void addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,ContentResponseBean contentResponseBean) throws DocumentException {
// Add label
Map<String, Boolean> stateFieldMap= new HashMap<>();
Paragraph labelParagraph = new Paragraph(label, labelFont);
document.add(labelParagraph);
float leftMargin = 20f;
PdfContentByte canvas = writer.getDirectContent();
// Setting the color and width of the line
@@ -204,8 +192,6 @@ public class PdfDao {
if (yPos <= 140) {
// If xEnd is less than or equal to 200, generate a new page
totalPages++;
document.newPage();
} // Add a gap between the label and value
document.add(new Paragraph(" ")); // Adding an empty paragraph for spacing
@@ -235,44 +221,13 @@ public class PdfDao {
// Finally, add the table to the document
document.add(valueTable);
} else {
boolean containsThreeValues = false; // Variable to track if any map contains three keys
List<Map<String, Object>> dataList = (List<Map<String, Object>>) value; // Cast Object to List of Maps
for (Map<String, Object> entry : dataList) {
if (entry.size() == 3) { // Check if the current map has three keys
containsThreeValues = true; // If found, set the variable to true
break; // No need to check further, exit loop
}
}
List<Map<String, String>> extractedData = new ArrayList<>(); // To hold extracted data
for (Map<String, Object> entry : dataList) {
Map<String, String> extractedMap = new HashMap<>(); // To hold the current extracted row of data
}
else if (!list.isEmpty() && list.get(0) instanceof Map<?, ?>) {
Object object = value;
String stringvalue = Utils.convertToString(object);
List<Map<String, Object>> fieldValueList = Utils.convertJsonStringIntoJsonList(stringvalue);
List<String> keys = new ArrayList<>(entry.keySet()); // Get all keys in the current map
// Handle based on the number of keys in the map
if (Boolean.FALSE.equals(containsThreeValues) && (keys.size() == 2 || keys.size()<2)) {
// Treat the first key as the "key" and second key as the "value"
String heading = (String) entry.get(keys.get(0)); // Get value of first key
String value1 = (String) entry.get(keys.get(1)); // Get value of second key
extractedMap.put(heading,value1); // Store the first key's value as "heading"
} if (Boolean.TRUE.equals(containsThreeValues) ) {
String amount="";
// Treat the first as number, second as description, third as amount
if(keys.size()==3){
amount = (String) entry.get(keys.get(2)); // Third key's value
}
String number = (String) entry.get(keys.get(0)); // First key's value
String description = (String) entry.get(keys.get(1)); // Second key's value
// Store the combined result as a value in the map, with a suitable key
String combinedValue = number + "; " + description + "; " + amount; // Concatenate them as a single value
extractedMap.put("combined", combinedValue); // Store as a single entry, key as "combined"
}
extractedData.add(extractedMap); // Add each extracted map to the list
}
document=createPdfTable(extractedData,document);
document = createPdfTable(fieldValueList, document, contentResponseBean);
}
}
else {
@@ -289,150 +244,89 @@ public class PdfDao {
}
document.add(new Paragraph("\n")); // Add line break after each value
return totalPages;
}
private Document createPdfTable(List<Map<String, String>> extractedData,Document document) throws DocumentException {
// Create a PdfPTable with 2 columns
PdfPTable table = new PdfPTable(2); // Initial assumption for 2 columns
private Document createPdfTable(List<Map<String, Object>> extractedData, Document document, ContentResponseBean contentResponseBean) throws DocumentException {
// Create a PdfPTable with dynamic column count based on stateFieldMap size
Map<String, String> stateFieldMap = new HashMap<>();
// Populate stateFieldMap from contentResponseBean settings
contentResponseBean.getSettings().stream()
.filter(setting -> "table_columns".equals(setting.getName())) // Check for "table_columns"
.map(SettingResponseBean::getValue)
.filter(Objects::nonNull) // Ensure value is not null
.filter(settingValue -> settingValue instanceof Map) // Ensure value is a Map
.map(settingValue -> (Map<String, Object>) settingValue) // Cast to Map
.map(valueMap -> (List<Map<String, Object>>) valueMap.get("stateFieldData")) // Extract stateFieldData list
.filter(Objects::nonNull) // Ensure stateFieldData is not null
.flatMap(List::stream) // Flatten the list of field data maps
.forEach(fieldData -> {
String fieldName = (String) fieldData.get("name"); // Get the name field
String fieldDataValue = (String) fieldData.get("label"); // Get the predefined field
if (fieldName != null && fieldDataValue != null) {
stateFieldMap.put(fieldName, fieldDataValue);
}
});
PdfPTable table = new PdfPTable(stateFieldMap.size()); // Number of columns equals the number of map entries
table.setWidthPercentage(100); // Set table width to 100%
table.setTableEvent(new RoundedBorderEvent());
Font textFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new BaseColor(105, 105, 105)); // Gray text
boolean combinedHeaderAdded = false; // Flag to track if headers for combined have been added
float rowHeight = 50f; // Example row height, adjust as necessary
float rowHeight = 20f; // Example row height
float maxTableHeight = 700f; // Maximum height of the table before a page break
float[] columnWidths = {0.7f, 0.3f};
table.setWidths(columnWidths);
boolean headersAdded = false; // Flag to check if headers have been added
// Iterate through extracted data to populate the table
for (Map<String, Object> row : extractedData) {
// Add headers once
if (!headersAdded) {
for (Map.Entry<String, String> stateField : stateFieldMap.entrySet()) {
String headerValue = stateField.getValue(); // Header text
// Add table header
// Populate the table with extracted data and style rows
for (Map<String, String> row : extractedData) {
for (Map.Entry<String, String> entry : row.entrySet()) {
String key = entry.getKey(); // This will give you the key
String value = entry.getValue(); // This will give you the value
PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header
headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
// Check if the current entry is for the combined section
if ("combined".equals(key)) {
// Ensure the combined header is added only once
if (!combinedHeaderAdded) {
// Create a new table for combined entries
table = new PdfPTable(3); // 3 columns for combined entries
PdfPCell headerCell1 = new PdfPCell(new Phrase("Number"));
headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
table.addCell(headerCell1);
PdfPCell headerCell2 = new PdfPCell(new Phrase("Details"));
headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
table.addCell(headerCell2);
PdfPCell headerCell3 = new PdfPCell(new Phrase("Amount"));
headerCell3.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell3.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
table.addCell(headerCell3);
combinedHeaderAdded = true; // Mark header as added
}
// Split the value for "combined" into separate parts
String[] combinedValues = value.split("; ");
// Check if we have 3 parts (number, description, amount)
String number = combinedValues[0]; // 1st part (number)
String description = combinedValues[1]; // 2nd part (description)
String amount = "";
if (combinedValues.length == 3) {
amount = combinedValues[2]; // 3rd part (amount)
}
// Create PDF cells using the split values
PdfPCell cellNumber = new PdfPCell(new Phrase(number, textFont)); // Cell for number
PdfPCell cellDescription = new PdfPCell(new Phrase(description, textFont)); // Cell for description
PdfPCell cellAmount = new PdfPCell(new Phrase(amount, textFont)); // Cell for amount
// Set row background color for combined values
cellNumber.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for combined rows
cellDescription.setBackgroundColor(new BaseColor(239, 243, 248));
cellAmount.setBackgroundColor(new BaseColor(239, 243, 248));
// Set cell height and add rounded borders
// cellNumber.setFixedHeight(rowHeight);
// cellDescription.setFixedHeight(rowHeight);
// cellAmount.setFixedHeight(rowHeight);
cellNumber.setMinimumHeight(20f); // Set minimum height for better appearance
cellDescription.setMinimumHeight(20f); // Set minimum height for better appearance
cellAmount.setMinimumHeight(20f); // Set minimum height for better appearance
cellNumber.setPadding(7f);
cellDescription.setPadding(7f);
cellAmount.setPadding(7f);
// Add the cells to the table only once
table.addCell(cellNumber);
table.addCell(cellDescription);
table.addCell(cellAmount);
} else {
if (!combinedHeaderAdded) {
// Create a new table for combined entries
table= new PdfPTable(2); // 3 columns for combined entries
table.setWidthPercentage(100);
PdfPCell headerCell1 = new PdfPCell(new Phrase("Details"));
headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
table.addCell(headerCell1);
PdfPCell headerCell2 = new PdfPCell(new Phrase("Amount"));
headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
table.addCell(headerCell2);
combinedHeaderAdded=true;
}
// Add cells for regular key-value pairs without headers
PdfPCell cellKey = new PdfPCell(new Phrase(key, textFont));
PdfPCell cellValue = new PdfPCell(new Phrase(value, textFont));
// Set background color for both cells
cellKey.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for other rows
cellValue.setBackgroundColor(new BaseColor(239, 243, 248));
cellKey.setPadding(7f);
cellValue.setPadding(7f);
// Set cell height and add rounded borders
cellKey.setFixedHeight(rowHeight);
cellValue.setFixedHeight(rowHeight);
// Add the cells to the table
table.addCell(cellKey);
table.addCell(cellValue);
table.addCell(headerCell); // Add the header cell to the table
}
if (table.getTotalHeight() + rowHeight > maxTableHeight) {
// Start a new page if needed
document.add(table);
table = new PdfPTable(2); // Reset table for new page
table.setWidthPercentage(100); // Reset width percentage
combinedHeaderAdded = false; // Reset header flag
headersAdded = true; // Prevent headers from being added again
}
// Add data rows matching stateFieldMap keys
for (Map.Entry<String, String> stateField : stateFieldMap.entrySet()) {
String stateKey = stateField.getKey(); // Get the key from stateFieldMap
if (row.containsKey(stateKey)) { // If row contains the stateKey
Object value = row.get(stateKey); // Get the value from the row map
PdfPCell dynamicCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", textFont));
dynamicCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell
dynamicCell.setMinimumHeight(rowHeight);
dynamicCell.setPadding(7f);
table.addCell(dynamicCell); // Add the dynamically created cell to the table
}
}
// Check if adding another row would exceed max height
if (table.getTotalHeight() + rowHeight > maxTableHeight) {
document.add(table); // Add the table to the document
document.newPage(); // Start a new page
table = new PdfPTable(stateFieldMap.size()); // Create a new table for the new page
table.setWidthPercentage(100); // Reset table width
headersAdded = false; // Reset the header flag for the new page
}
}
document.add(table); // Add the last table before returning
// Add the last table to the document
document.add(table);
// Check if adding a new row would exceed the maximum height
// Return the populated table
return document;
}
public static class RoundedBorderEvent implements PdfPTableEvent {
@Override
public void tableLayout(PdfPTable table, float[][] widths, float[] heights,
@@ -453,89 +347,98 @@ public class PdfDao {
canvas.stroke();
}
}
public List<FieldLabelValuePairRequest> getFormFieldsToLabels(FormApplicationResponse responseBean) {
public List<FieldLabelValuePairRequest> getFormFieldsToLabels(FormApplicationResponse responseBean,PdfWriter writer,Document document) {
List<FieldLabelValuePairRequest> labelValuePairs = new ArrayList<>();
// Iterate through each form in the application response
List<ApplicationFormFieldResponseBean> formFields = responseBean.getFormFields();
List<ContentResponseBean> contents = responseBean.getContent();
// Iterate through each formField in the current form
for (ApplicationFormFieldResponseBean formField : formFields) {
String fieldId = formField.getFieldId();
Object fieldValue = formField.getFieldValue();
// Find the content in the form that matches the fieldId
Optional<ContentResponseBean> matchingContent = contents.stream()
.filter(content -> content.getId().equals(fieldId))
.findFirst();
Font labelFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,new BaseColor(113,121,126)); // Light grey);
Font valueFont=FontFactory.getFont(FontFactory.HELVETICA_BOLD,10,new BaseColor(178, 190, 181));
// If the content with the matching fieldId is found, create a label-value pair
if (matchingContent.isPresent()) {
String name = matchingContent.get().getName();
ContentResponseBean content = matchingContent.get();
// Get form fields and contents from the response
List<ApplicationFormFieldResponseBean> formFields = responseBean.getFormFields();
List<ContentResponseBean> contents = responseBean.getContent();
// Find the setting where the name is "label"
String contentLabel = content.getSettings().stream()
.filter(setting -> "label".equals(setting.getName())) // Filter settings by name
.map(SettingResponseBean::getValue) // Extract the value from the matching setting
.map(Object::toString) // Convert the value to a string
.findFirst() // Get the first matching value
.orElse(null); // If no match is found, set label to null
// Iterate through each content in the response
for (ContentResponseBean content : contents) {
String contentId = content.getId(); // Content ID
String label = content.getLabel(); // Content label
String name = content.getName(); // Content name
Object fieldValue = null;
if (name.equals("fileupload")) {
String contentLabel = content.getSettings().stream()
.filter(setting -> "label".equals(setting.getName())) // Filter settings by name
.map(SettingResponseBean::getValue) // Extract the value from the matching setting
.map(Object::toString) // Convert the value to a string
.findFirst() // Get the first matching value
.orElse(null); // If no match is found, set label to null
// Find the form field in the response that matches the contentId
Optional<ApplicationFormFieldResponseBean> matchingFormField = formFields.stream()
.filter(formField -> formField.getFieldId().equals(contentId))
.findFirst();
// Step 1: Check if fieldValue is an instance of List<DocumentResponseBean>
if (fieldValue instanceof List<?> && ((List<?>) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) {
// Step 2: Safely cast to List<DocumentResponseBean>
List<DocumentResponseBean> documentList = (List<DocumentResponseBean>) fieldValue;
// If a matching form field is found, process its value
if (matchingFormField.isPresent()) {
ApplicationFormFieldResponseBean formField = matchingFormField.get();
fieldValue = formField.getFieldValue();
// Step 3: Extract names from the document list
List<String> names = documentList.stream()
.map(DocumentResponseBean::getName) // Extract the name from each DocumentResponseBean
.collect(Collectors.toList());
// If fieldValue is null, set it to an empty string
if (fieldValue == null) {
fieldValue = "";
}
fieldValue=names;
}
// Process 'fileupload' and 'checkboxes' cases as in the original logic
if (name.equals("fileupload")) {
if (fieldValue instanceof List<?> && ((List<?>) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) {
List<DocumentResponseBean> documentList = (List<DocumentResponseBean>) fieldValue;
List<String> names = documentList.stream()
.map(DocumentResponseBean::getName)
.collect(Collectors.toList());
fieldValue = names;
}
if(name.equals("checkboxes")) {
List<String> check = (List<String>) fieldValue;
List<SettingResponseBean> settingResponseBeans = matchingContent.get().getSettings();
for (SettingResponseBean settingResponseBean : settingResponseBeans) {
// Initialize a list to hold matched labels for each SettingResponseBean
List<String> matchedLabels = new ArrayList<>();
if (settingResponseBean.getValue() instanceof List<?>) {
} else if (name.equals("checkboxes")) {
List<String> check = (List<String>) fieldValue;
List<SettingResponseBean> settingResponseBeans = content.getSettings();
List<String> matchedLabels = new ArrayList<>();
List<?> valueList = (List<?>) settingResponseBean.getValue();
if (!valueList.isEmpty() && valueList.get(0) instanceof Map<?, ?>) {
// Cast to List<Map<String, String>>
List<Map<String, String>> options = (List<Map<String, String>>) valueList;
for (Map<String, String> field : options) {
for (String val : check) {
String name1=field.get("name");
if (val.equals(name1)) { // Check if the key exists in the current field map
String label = field.get("label"); // Extract the label
if (field != null) { // Check if the value is not null
matchedLabels.add(label); // Add the value to the matchedValues list
}
}
for (SettingResponseBean settingResponseBean : settingResponseBeans) {
if (settingResponseBean.getValue() instanceof List<?>) {
List<Map<String, String>> options = (List<Map<String, String>>) settingResponseBean.getValue();
for (Map<String, String> field : options) {
for (String val : check) {
String name1 = field.get("name");
if (val.equals(name1)) {
String labelVal = field.get("label");
if (labelVal != null) {
matchedLabels.add(labelVal);
}
}
fieldValue = matchedLabels;
}
}
}
}
// Add the label-value pair to the list
fieldValue = findLabelInOptions(matchingContent.get().getSettings(), fieldValue);
labelValuePairs.add(new FieldLabelValuePairRequest(contentLabel, fieldValue));
fieldValue = matchedLabels;
}
// Further processing of field value (e.g., finding labels in options)
fieldValue = findLabelInOptions(content.getSettings(), fieldValue);
} else {
// If no matching form field is found, store contentId with an empty string
fieldValue = "";
}
try {
addLabelValuePair(writer,document, contentLabel, fieldValue, labelFont,valueFont,content);
} catch (DocumentException e) {
log.error("Error checking object: " + e.getMessage(), e);
}
// } labelValuePairs.add(new FieldLabelValuePairRequest(contentLabel, fieldValue));
}
return labelValuePairs;
}
public static Object findLabelInOptions(List<SettingResponseBean> settings, Object valueToFind) {
ObjectMapper objectMapper = new ObjectMapper();

View File

@@ -31,6 +31,8 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundExcep
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException;
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException;
import static org.apache.commons.lang3.StringUtils.isEmpty;
public class Utils {
@@ -315,4 +317,56 @@ public class Utils {
}
return content.trim().replace(" ", "_");
}
public static List<Map<String, Object>> convertJsonStringIntoJsonList(String jsonString) {
try {
if(isEmpty(jsonString))
{
return new ArrayList<>();
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
return mapper.readValue(jsonString, List.class);
} catch (Exception e) {
log.error(e.getMessage());
}
return null;
}
public static String convertToString(Object input) {
if (input == null) {
return "null"; // Return string "null" for null input
}
if (input instanceof String) {
return (String) input; // Return the string directly if input is a string
}
if (input instanceof Collection<?>) {
// Handle collections (List, Set, etc.)
return convertCollectionToString((Collection<?>) input);
}
if (input instanceof Map<?, ?>) {
// Handle maps
return convertMapToString((Map<?, ?>) input);
}
// For other types (like Integer, Boolean, etc.), use toString()
return input.toString();
}
private static String convertCollectionToString(Collection<?> collection) {
try {
return mapper.writeValueAsString(collection); // Convert the collection to a JSON string
} catch (JsonProcessingException e) {
throw new RuntimeException("Error converting collection to string", e);
}
}
private static String convertMapToString(Map<?, ?> map) {
try {
return mapper.writeValueAsString(map); // Convert the map to a JSON string
} catch (JsonProcessingException e) {
throw new RuntimeException("Error converting map to string", e);
}
}
}