瀏覽代碼

0708 demo version

master
kelvinsuen 1 月之前
父節點
當前提交
1b7d16413f
共有 3 個檔案被更改,包括 332 行新增16 行删除
  1. +241
    -12
      src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java
  2. +77
    -2
      src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java
  3. +14
    -2
      src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java

+ 241
- 12
src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java 查看文件

@@ -1,5 +1,8 @@
package com.ffii.lioner.modules.lioner.pdf.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

@@ -14,17 +17,29 @@ import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;

import com.ffii.lioner.modules.lioner.pdf.entity.Pdf;
import com.ffii.lioner.modules.lioner.pdf.entity.PdfRepository;
import com.ffii.lioner.modules.lioner.commonField.entity.CommonField;
import com.ffii.lioner.modules.lioner.commonField.service.CommonFieldService;
import com.ffii.lioner.modules.lioner.entity.ImpEvent;
import com.ffii.lioner.modules.lioner.pdf.req.UpdatePdfReq;
import com.ffii.lioner.modules.lioner.service.FileService;
import com.ffii.lioner.modules.common.SecurityUtils;
import com.ffii.lioner.modules.common.service.AuditLogService;
import com.ffii.lioner.modules.master.entity.SubDivision;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.io.source.ByteArrayOutputStream;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffii.core.exception.NotFoundException;
import com.ffii.core.exception.UnprocessableEntityException;
@@ -35,6 +50,7 @@ import com.ffii.core.utils.JsonUtils;
import com.ffii.core.utils.Params;

import jakarta.persistence.Table;
import com.ffii.lioner.modules.lioner.pdf.web.Pdf2Controller;

@Service
public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfRepository> {
@@ -43,11 +59,13 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
private AuditLogService auditLogService;
private FileService fileService;
private CommonFieldService commonFieldService;
public PdfService(JdbcDao jdbcDao, PdfRepository repository, AuditLogService auditLogService, FileService fileService) {
public PdfService(JdbcDao jdbcDao, PdfRepository repository, AuditLogService auditLogService, FileService fileService, CommonFieldService commonFieldService) {
super(jdbcDao, repository);
this.auditLogService = auditLogService;
this.fileService = fileService;
this.commonFieldService = commonFieldService;
}

// public Map<String,Object> getAuditLogObject(Map<String,Object> req){
@@ -130,10 +148,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
System.out.println(e);
}

// Save the PDF data to the database
// File pdfForm = new PdfForm();
// pdfForm.setPdfData(pdfData);
// pdfFormRepository.save(pdfForm); // Assuming you have autowired this repository
saveCmField(convertMultipartFileToFile(file), instance);

response.put("message", "PDF saved successfully.");
// response.put("id", pdfForm.getId().toString()); // Return the ID of the saved PDF
@@ -162,18 +177,136 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
return response;
}

public byte[] getTemplateForm() {
// Ensure the template PDF is in src/main/resources/template/pdf
ClassPathResource pdfFile = new ClassPathResource(pdf_path + "HSBC B24102883_fillable_Financial Needs Analysis for Individual Nov2024.pdf");
if (!pdfFile.exists()) {
throw new UnprocessableEntityException("PDF template not found.");
// Converter -- WIP
public File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
// Convert MultipartFile to byte array
byte[] bytes = multipartFile.getBytes();

// Create a temporary file
File file = File.createTempFile("tempFile", multipartFile.getOriginalFilename());

// Write byte array to the file
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
}
try (InputStream is = pdfFile.getInputStream()) {
return is.readAllBytes();

return file;
}

public byte[] getTemplateForm(Long templateId, Long clientId) {
// Ensure the template PDF is in src/main/resources/template/pdf
String filename;
switch (templateId.intValue()) {
case 1:
filename = "IDA.pdf";
break;
case 2:
filename = "FNA.pdf";
break;
case 3:
filename = "HSBCFIN.pdf";
break;
default:
filename = "HSBCFIN.pdf";
};
ClassPathResource pdfFile = new ClassPathResource(pdf_path + filename);
byte[] pdfBytes;
byte[] modifiedPdfBytes;
try (InputStream is = pdfFile.getInputStream()) {
pdfBytes = is.readAllBytes();
modifiedPdfBytes = pdfBytes;
} catch (Exception e) {
throw new UnprocessableEntityException("Fail to load PDF: " + e);
}

try (ByteArrayInputStream inputStream = new ByteArrayInputStream(pdfBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

PdfReader reader = new PdfReader(inputStream);
PdfWriter writer = new PdfWriter(outputStream);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);

if (form != null) {
// --- START DEBUGGING CODE TO LIST ALL PDF FORM FIELDS ---
// logger.info("--- Listing all form fields in the PDF (for ID: {}) ---", id);
// if (form.getFormFields().isEmpty()) {
// logger.info("No form fields found in this PDF.");
// } else {
// form.getFormFields().forEach((fieldName, pdfFormField) -> {
// logger.info(" - Field Name: '{}', Type: '{}'", fieldName, pdfFormField.getFormType());
// });
// }
// logger.info("--- End of form fields list ---");
// --- END DEBUGGING CODE ---

// Load common field data
Long commonFieldId = commonFieldService.getByClientId(clientId);
// logger.info("id? " + id);
CommonField commonField = commonFieldService.find(commonFieldId).orElse(null);

if(commonField == null){
logger.info("No common field data found for clientId: " + clientId);
// do nothing
} else {
// It's highly recommended to check if the field exists before setting its value
// This prevents NullPointerExceptions if a field is missing in a template

if(templateId.intValue() == 1){ // This is IDA
logger.info("Processing IDA form (ID: 1)");
setValueIfPresent(form, "fill_6", commonField.getName(), "commonField.getName()");
setValueIfPresent(form, "fill_7", commonField.getNameChi(), "commonField.getNameChi()");
setValueIfPresent(form, "fill_11", commonField.getIdCard(), "commonField.getIdCard()");

} else if(templateId.intValue() == 2){ // This is FNA
logger.info("Processing FNA form (ID: 2)");
setValueIfPresent(form, "fna_a_name", commonField.getName(), "commonField.getName()");
setValueIfPresent(form, "fna_a_birth", commonField.getDateOfBirth(), "commonField.getDateOfBirth()");
setValueIfPresent(form, "fna_a_occupation", commonField.getOccupation(), "commonField.getOccupation()");

} else if(templateId.intValue() == 3){ // This is HSBCFIN
logger.info("Processing HSBCFIN form (ID: 3)");
setValueIfPresent(form, "fill_3", commonField.getName(), "commonField.getName()");
setValueIfPresent(form, "fill_4", commonField.getNameChi(), "commonField.getNameChi()");
setValueIfPresent(form, "fill_5", commonField.getGender(), "commonField.getGender()");
setValueIfPresent(form, "fill_6", commonField.getDateOfBirth(), "commonField.getDateOfBirth()"); // Note: fill_6 used here again
setValueIfPresent(form, "fill_9", commonField.getOccupation(), "commonField.getOccupation()");
}

// These fields are set unconditionally if commonField is not null
// Ensure these fields exist across all your templates or handle them conditionally
setValueIfPresent(form, "address", "123 Main St, Anytown, USA", "hardcoded address");
setValueIfPresent(form, "dateOfBirth", "01/01/1990", "hardcoded dateOfBirth");
}

//form.flattenFields(); // Flatten fields after setting all values

} else {
// logger.warn("No AcroForm found in PDF for ID: " + id + ". PDF might not have fillable fields.");
}

pdfDoc.close();
modifiedPdfBytes = outputStream.toByteArray();
logger.info("Modified PDF byte array length: " + modifiedPdfBytes.length);

} catch (IOException e) {
// logger.error("Error processing PDF with iText for ID: " + id, e);
}




if (!pdfFile.exists()) {
throw new UnprocessableEntityException("PDF template not found.");
}
// try (InputStream is = pdfFile.getInputStream()) {
// return pdfBytes;
// } catch (Exception e) {
// throw new UnprocessableEntityException("Fail to load PDF: " + e);
// }
return modifiedPdfBytes;
// return fileService.getfileBlob((long) 2);
}

@@ -245,4 +378,100 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
return jdbcDao.queryForInt(sql.toString(), Map.of("name", name));
}



public void saveCmField(File file, Pdf record) throws IOException {
// byte[] pdfBytes = Files.readAllBytes(file.toPath());

// try (FileOutputStream fos = new FileOutputStream(file)) {
// IOUtils.write(pdfBytes, fos);
// }

//PDDocument document = PDDocument.load(targetLocation.toFile());
PDDocument document = Loader.loadPDF(file); // Changed!
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();

logger.info("acroForm? " + (acroForm != null) );
if (acroForm != null) {
//create CommonField if not exists for this client Id
Long id = commonFieldService.getByClientId(record.getClientId());
logger.info("id? " + id);
CommonField commonField = null;
if(id > 0){
commonField = commonFieldService.find(id).orElse(new CommonField());
}else{
commonField = new CommonField();
}
//logger.info("commonField? " + commonField.toString());
commonField.setClientId(record.getClientId());

logger.info("commonField? " + commonField.getId());
// Example: Iterate through fields and print values
for (PDField field : acroForm.getFields()) {
String fieldName = field.getPartialName();
String fieldValue = field.getValueAsString();

if (record.getTemplateId().intValue() == 1) {
logger.info("IDA ");

switch (fieldName) {
case "fill_6" -> commonField.setName(fieldValue);
case "fill_7" -> commonField.setNameChi(fieldValue);
case "fill_11" -> commonField.setIdCard(fieldValue);
};
}

if(record.getTemplateId().intValue() == 2){
logger.info("FNA ");

switch (fieldName) {
case "fna_a_name" -> commonField.setName(fieldValue);
case "fna_a_birth" -> commonField.setDateOfBirth(fieldValue);
case "fna_a_occupation" -> commonField.setOccupation(fieldValue);
};
}

if(record.getTemplateId().intValue() == 3){
logger.info("HSBCFIN ");
switch (fieldName) {
case "fill_3" -> commonField.setName(fieldValue);
case "fill_4" -> commonField.setNameChi(fieldValue);
case "fill_5" -> commonField.setGender(fieldValue);
case "fill_6" -> commonField.setDateOfBirth(fieldValue);

case "fill_9" -> commonField.setOccupation(fieldValue);
};
}
logger.info("end Field: " + field.getPartialName() + ", Value: " + field.getValueAsString());
// You can save this data to a database, or perform other operations
}

commonFieldService.save(commonField);
}
logger.info("ended");
document.close();
logger.info("closed");
}

private void setValueIfPresent(PdfAcroForm form, String fieldName, String value, String valueSource) {
PdfFormField field = form.getField(fieldName);
if (field != null) {
if (value != null) {
try {
field.setValue(value);
// logger.info("Set field '{}' to value '{}' (from {})", fieldName, value, valueSource);
} catch (Exception e) {
// logger.error("Error setting value for field '{}' with value '{}' (from {}): {}", fieldName, value, valueSource, e.getMessage());
}
} else {
// logger.warn("Value for field '{}' (from {}) is null. Skipping setting value.", fieldName, valueSource);
}
} else {
// logger.warn("PDF field '{}' not found in the document. Skipping setting value.", fieldName);
}
}
}

+ 77
- 2
src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java 查看文件

@@ -39,6 +39,7 @@ import org.springframework.web.multipart.MultipartFile;

import com.ffii.lioner.modules.lioner.commonField.entity.CommonField;
import com.ffii.lioner.modules.lioner.commonField.service.CommonFieldService;
import com.ffii.lioner.modules.lioner.pdf.entity.Pdf;
import com.ffii.lioner.modules.lioner.pdf.service.PdfService;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
@@ -361,8 +362,82 @@ public class Pdf2Controller {
return ResponseEntity.ok("PDF saved successfully at " + file.getAbsolutePath());
} catch (IOException e) {
return ResponseEntity.status(500).body("Error saving PDF: " + e.getMessage());
}
}
}

public void saveCmField(File file, Pdf record) throws IOException {
// byte[] pdfBytes = Files.readAllBytes(file.toPath());

// try (FileOutputStream fos = new FileOutputStream(file)) {
// IOUtils.write(pdfBytes, fos);
// }

//PDDocument document = PDDocument.load(targetLocation.toFile());
PDDocument document = Loader.loadPDF(file); // Changed!
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();

logger.info("acroForm? " + (acroForm != null) );
if (acroForm != null) {
//create CommonField if not exists for this client Id
Long id = commonFieldService.getByClientId(record.getClientId());
logger.info("id? " + id);
CommonField commonField = null;
if(id > 0){
commonField = commonFieldService.find(id).orElse(new CommonField());
}else{
commonField = new CommonField();
}
//logger.info("commonField? " + commonField.toString());
commonField.setClientId(record.getClientId());

logger.info("commonField? " + commonField.getId());
// Example: Iterate through fields and print values
for (PDField field : acroForm.getFields()) {
String fieldName = field.getPartialName();
String fieldValue = field.getValueAsString();

if (record.getTemplateId().intValue() == 1) {
logger.info("IDA ");

switch (fieldName) {
case "fill_6" -> commonField.setName(fieldValue);
case "fill_7" -> commonField.setNameChi(fieldValue);
case "fill_11" -> commonField.setIdCard(fieldValue);
};
}

if(record.getTemplateId().intValue() == 2){
logger.info("FNA ");

switch (fieldName) {
case "fna_a_ name" -> commonField.setName(fieldValue);
case "fna_a_birth" -> commonField.setDateOfBirth(fieldValue);
case "fna_a_occupation" -> commonField.setOccupation(fieldValue);
};
}

if(record.getTemplateId().intValue() == 3){
logger.info("HSBCFIN ");
switch (fieldName) {
case "fill_3" -> commonField.setName(fieldValue);
case "fill_4" -> commonField.setNameChi(fieldValue);
case "fill_5" -> commonField.setGender(fieldValue);
case "fill_6" -> commonField.setDateOfBirth(fieldValue);

case "fill_9" -> commonField.setOccupation(fieldValue);
};
}
logger.info("end Field: " + field.getPartialName() + ", Value: " + field.getValueAsString());
// You can save this data to a database, or perform other operations
}

commonFieldService.save(commonField);
}
logger.info("ended");
document.close();
logger.info("closed");
}
}

+ 14
- 2
src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java 查看文件

@@ -80,9 +80,21 @@ public class PdfController {

// Endpoint to serve the initial template PDF
@GetMapping(value = "/template", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getPdfTemplate() throws IOException {
public ResponseEntity<byte[]> getPdfTemplate(@RequestParam Long templateId, @RequestParam Long clientId) throws IOException {
byte[] pdfBytes = pdfService.getTemplateForm();
byte[] pdfBytes = pdfService.getTemplateForm(templateId, clientId);

HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("inline", "template_form.pdf");
headers.setContentType(MediaType.APPLICATION_PDF);
return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK);
}

// Get template by template id (Unused now)
@GetMapping(value = "/template/{id}", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getPdfTemplateById(@PathVariable Long id) throws IOException {
byte[] pdfBytes = pdfService.getTemplateForm(id, (long) 0);

HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("inline", "template_form.pdf");


Loading…
取消
儲存