ソースを参照

no message

master
コミット
02589968ec
3個のファイルの変更495行の追加141行の削除
  1. +144
    -0
      src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfMergeService.java
  2. +166
    -127
      src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java
  3. +185
    -14
      src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java

+ 144
- 0
src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfMergeService.java ファイルの表示

@@ -0,0 +1,144 @@
package com.ffii.lioner.modules.lioner.pdf.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.springframework.stereotype.Service;

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.utils.PdfMerger;

@Service
public class PdfMergeService {

public void mergePdfs() throws IOException {
// Load PDF A and PDF B
String filePathA = "C:\\dev\\pdf\\pdfA.pdf";
File fileA = new File(filePathA);

String filePathB = "C:\\dev\\pdf\\pdfB.pdf";
File fileB = new File(filePathB);

String outputPath = "C:\\dev\\pdf\\pdfOut.pdf";

try (
PDDocument pdfA = Loader.loadPDF(fileA);
PDDocument pdfB = Loader.loadPDF(fileB);
PDDocument mergedPdf = new PDDocument()) {

for (int i = 0; i < pdfB.getNumberOfPages(); i++) {
PDPage page = pdfB.getPage(i);
mergedPdf.addPage(page);
}

//this is for remove the password and copy the whole pdf
//pdfB.setAllSecurityToBeRemoved(true);
//pdfB.save(new File(outputPath));
// Save the merged PDF
mergedPdf.save(new File(outputPath));
}
}

public byte[] mergePdfsItext7(String formCode, byte[] pdfABytes, byte[] pdfBBytes) throws IOException {

// Defined constants for clarity
final int IDA_SIG_PAGE = 11; // Page to skip for IDA
final int FNA_SIG_PAGE = 7; // Page to skip for FNA
final int HSBC_REP_PAGE = 11; // Page to replace for HSBCFIN
// Use java.io.ByteArrayOutputStream
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
PdfWriter writer = new PdfWriter(baos);
PdfDocument mergedPdf = new PdfDocument(writer);
PdfMerger merger = new PdfMerger(mergedPdf);

// 1. Process PDF A (The primary document)
try (PdfReader readerA = new PdfReader(new ByteArrayInputStream(pdfABytes));
PdfDocument docA = new PdfDocument(readerA)) {
int totalPagesA = docA.getNumberOfPages();
if ("IDA".equals(formCode) && totalPagesA >= IDA_SIG_PAGE) {
// --- IDA: SKIP page 11, then merge rest of A ---
// Copy pages 1 through 10 (IDA_SIG_PAGE - 1)
if (IDA_SIG_PAGE > 1) {
merger.merge(docA, 1, IDA_SIG_PAGE - 1);
}
// Copy pages 12 through the end (IDA_SIG_PAGE + 1)
if (totalPagesA > IDA_SIG_PAGE) {
merger.merge(docA, IDA_SIG_PAGE + 1, totalPagesA);
}
} else if ("FNA".equals(formCode) && totalPagesA >= FNA_SIG_PAGE) {
// --- FNA: SKIP page 7, then merge rest of A ---
// Copy pages 1 through 6 (FNA_SIG_PAGE - 1)
if (FNA_SIG_PAGE > 1) {
merger.merge(docA, 1, FNA_SIG_PAGE - 1);
}
// Copy pages 8 through the end (FNA_SIG_PAGE + 1)
if (totalPagesA > FNA_SIG_PAGE) {
merger.merge(docA, FNA_SIG_PAGE + 1, totalPagesA);
}
} else if ("HSBCFIN".equals(formCode) && totalPagesA >= HSBC_REP_PAGE) {
// --- HSBCFIN: REPLACE page 11 with PDF B page 1 ---
// A. Copy pages 1 up to 10 (HSBC_REP_PAGE - 1)
if (HSBC_REP_PAGE > 1) {
merger.merge(docA, 1, HSBC_REP_PAGE - 1);
}
// B. Insert replacement page from PDF B (if available)
if (pdfBBytes != null && pdfBBytes.length > 0) {
try (PdfReader readerB = new PdfReader(new ByteArrayInputStream(pdfBBytes));
PdfDocument docB = new PdfDocument(readerB)) {
// Copy ONLY page 1 from docB
merger.merge(docB, 1, 1);
}
}
// C. Copy pages 12 through the end (HSBC_REP_PAGE + 1)
if (totalPagesA > HSBC_REP_PAGE) {
merger.merge(docA, HSBC_REP_PAGE + 1, totalPagesA);
}
} else {
// Default: Copy all pages from docA
merger.merge(docA, 1, totalPagesA);
}
}
// 2. Process PDF B (Only appended if IDA or FNA, as HSBCFIN already merged it)
if (pdfBBytes != null && pdfBBytes.length > 0) {
if ("IDA".equals(formCode) || "FNA".equals(formCode)){
try (PdfReader readerB = new PdfReader(new ByteArrayInputStream(pdfBBytes));
PdfDocument docB = new PdfDocument(readerB)) {
// Copy ONLY page 1 from docB to append as the last page
merger.merge(docB, 1, 1);
}
}
}

// 3. Close the merged PDF document
mergedPdf.close();
// 4. Return the resulting byte array
return baos.toByteArray();

} // baos is closed here
}
}

+ 166
- 127
src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java ファイルの表示

@@ -313,18 +313,20 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
FNA_textBox(form, commonField, client);
} else if("HSBCFIN".equals(formCode)){ // This is HSBCFIN
HSBCFIN_textBox(form, commonField, client);
}else if ("MLB03S".equals(formCode)) {
MLB03S_textBox(form, commonField, client);
} else if("MLFNA_EN".equals(formCode)){ // This is ML FNA EN
MLFNA_EN_textBox(form, commonField, client);
} else if("MLFNA_CHI".equals(formCode)){ // This is ML FNA CHI
MLFNA_EN_textBox(form, commonField, client);
} else if("SLFNA_EN".equals(formCode)){ // This is SL FNA EN
SLFNA_EN_textBox(form, commonField, client);
} else if("SLFNA_CHI".equals(formCode)){ // This is SL FNA CHI
SLFNA_EN_textBox(form, commonField, client);
}else if("SLAPP".equals(formCode)){
SLAPP_textBox(form, commonField, client);
}else if("HSBCA31".equals(formCode)){ // This is HSBC A31
HSBCA31_textBox(form, commonField, client);
}else if ("MLB03S".equals(formCode)) {
MLB03S_textBox(form, commonField, client);
}else if("SLGII".equals(formCode)){
SLGII_textBox(form, commonField, client);
}
@@ -385,16 +387,20 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
FNA_checkBox(form2, commonField);
} else if ("HSBCFIN".equals(formCode)) {
HSBCFIN_checkBox(form2, commonField);
} else if("MLFNA_EN".equals(formCode)){ // This is ML FNA EN
}else if ("MLB03S".equals(formCode)) {
MLB03S_checkBox(form2, commonField);
}else if("MLFNA_EN".equals(formCode)){ // This is ML FNA EN
MLFNA_EN_checkBox(form2, commonField);
} else if("MLFNA_CHI".equals(formCode)){ // This is ML FNA CHI
MLFNA_EN_checkBox(form2, commonField);
} else if("SLFNA_EN".equals(formCode)){ // This is SL FNA EN
SLFNA_EN_checkBox(form2, commonField);
} else if("SLFNA_CHI".equals(formCode)){ // This is SL FNA CHI
SLFNA_EN_checkBox(form2, commonField);
}else if("SLAPP".equals(formCode)){
SLAPP_checkBox(form2, commonField);
} else if("HSBCA31".equals(formCode)){
HSBCA31_checkBox(form2, commonField);
}else if ("MLB03S".equals(formCode)) {
MLB03S_checkBox(form2, commonField);
}else if ("SLGII".equals(formCode)) {
SLGII_checkBox(form2, commonField);
}
@@ -507,7 +513,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
/* Page7 Start */
setValueIfPresent(form, "fill_11_7", commonField.getInsuranceCompany1_1());
setValueIfPresent(form, "fill_11_7_1", commonField.getInsuranceCompany1_2());
setValueIfPresent(form, "fill_11_7_2", commonField.getInsuranceCompany1_3());
//setValueIfPresent(form, "fill_11_7_2", commonField.getInsuranceCompany1_3());
setValueIfPresent(form, "fill_12_7_1", commonField.getOthers().get("insuranceSumInsured1_1"));
setValueIfPresent(form, "fill_12_7_2", commonField.getOthers().get("insuranceSumInsured1_2"));
setValueIfPresent(form, "fill_12_7_3", commonField.getOthers().get("insuranceSumInsured1_3"));
@@ -520,7 +526,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
setValueIfPresent(form, "fill_13_7", commonField.getInsuranceCompany2_1());
setValueIfPresent(form, "fill_13_7_1", commonField.getInsuranceCompany2_2());
setValueIfPresent(form, "fill_13_7_2", commonField.getInsuranceCompany2_3());
//setValueIfPresent(form, "fill_13_7_2", commonField.getInsuranceCompany2_3());
setValueIfPresent(form, "fill_14_7_1", commonField.getOthers().get("insuranceSumInsured2_1"));
setValueIfPresent(form, "fill_14_7_2", commonField.getOthers().get("insuranceSumInsured2_2"));
setValueIfPresent(form, "fill_14_7_3", commonField.getOthers().get("insuranceSumInsured2_3"));
@@ -528,7 +534,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
setValueIfPresent(form, "fill_3_7", commonField.getInsuranceYear2());
setValueIfPresent(form, "fill_15_7", commonField.getInsuranceCompany3_1());
setValueIfPresent(form, "fill_15_7_1", commonField.getInsuranceCompany3_2());
setValueIfPresent(form, "fill_15_7_2", commonField.getInsuranceCompany3_3());
//setValueIfPresent(form, "fill_15_7_2", commonField.getInsuranceCompany3_3());
setValueIfPresent(form, "fill_16_7_1", commonField.getOthers().get("insuranceSumInsured3_1"));
setValueIfPresent(form, "fill_16_7_2", commonField.getOthers().get("insuranceSumInsured3_2"));
setValueIfPresent(form, "fill_16_7_3", commonField.getOthers().get("insuranceSumInsured3_3"));
@@ -1346,7 +1352,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
setValueIfPresent(form, "4_1_name1_1", commonField.getInsuranceCompany1_1());
setValueIfPresent(form, "4_1_name1_2", commonField.getInsuranceCompany1_2());
setValueIfPresent(form, "4_1_name1_3", commonField.getInsuranceCompany1_3());
//setValueIfPresent(form, "4_1_name1_3", commonField.getInsuranceCompany1_3());
setValueIfPresent(form, "4_1_year1", commonField.getInsuranceYear1());
setValueIfPresent(form, "4_1_currency1", commonField.getInsuranceCurrency1());
setValueIfPresent(form, "4_1_sum1_1", commonField.getOthers().get("insuranceSumInsured1_1"));
@@ -1355,7 +1361,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
setValueIfPresent(form, "4_1_name2_1", commonField.getInsuranceCompany2_1());
setValueIfPresent(form, "4_1_name2_2", commonField.getInsuranceCompany2_2());
setValueIfPresent(form, "4_1_name2_3", commonField.getInsuranceCompany2_3());
//setValueIfPresent(form, "4_1_name2_3", commonField.getInsuranceCompany2_3());
setValueIfPresent(form, "4_1_year2", commonField.getInsuranceYear2());
setValueIfPresent(form, "4_1_currency2", commonField.getInsuranceCurrency2());
setValueIfPresent(form, "4_1_sum2_1", commonField.getOthers().get("insuranceSumInsured2_1"));
@@ -1364,7 +1370,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
setValueIfPresent(form, "4_1_name3_1", commonField.getInsuranceCompany3_1());
setValueIfPresent(form, "4_1_name3_2", commonField.getInsuranceCompany3_2());
setValueIfPresent(form, "4_1_name3_3", commonField.getInsuranceCompany3_3());
//setValueIfPresent(form, "4_1_name3_3", commonField.getInsuranceCompany3_3());
setValueIfPresent(form, "4_1_year3", commonField.getInsuranceYear3());
setValueIfPresent(form, "4_1_currency3", commonField.getInsuranceCurrency3());
setValueIfPresent(form, "4_1_sum3_1", commonField.getOthers().get("insuranceSumInsured3_1"));
@@ -1956,13 +1962,13 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
/* Page6 Start */
setValueIfPresent(form, "4_1_name1_1", commonField.getInsuranceCompany1_1());
setValueIfPresent(form, "4_1_name1_2", commonField.getInsuranceCompany1_2());
setValueIfPresent(form, "4_1_name1_3", commonField.getInsuranceCompany1_3());
//setValueIfPresent(form, "4_1_name1_3", commonField.getInsuranceCompany1_3());
setValueIfPresent(form, "4_1_name2_1", commonField.getInsuranceCompany2_1());
setValueIfPresent(form, "4_1_name2_2", commonField.getInsuranceCompany2_2());
setValueIfPresent(form, "4_1_name2_3", commonField.getInsuranceCompany2_3());
//setValueIfPresent(form, "4_1_name2_3", commonField.getInsuranceCompany2_3());
setValueIfPresent(form, "4_1_name3_1", commonField.getInsuranceCompany3_1());
setValueIfPresent(form, "4_1_name3_2", commonField.getInsuranceCompany3_2());
setValueIfPresent(form, "4_1_name3_3", commonField.getInsuranceCompany3_3());
//setValueIfPresent(form, "4_1_name3_3", commonField.getInsuranceCompany3_3());
setValueIfPresent(form, "4_1_year1", commonField.getInsuranceYear1());
setValueIfPresent(form, "4_1_year2", commonField.getInsuranceYear2());
setValueIfPresent(form, "4_1_year3", commonField.getInsuranceYear3());
@@ -2293,6 +2299,11 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
public List<Map<String,Object>> list(Map<String, Object> args){
StringBuilder sql = new StringBuilder("SELECT"
+ " (select concat('V', count(1) + 1) from filled_form where clientId = ff.clientId and templateId = ff.templateId and id < ff.id) as vNum, "
+ " (select f.id from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload1' and fr.refId = ff.id order by fr.id desc limit 1) as upload1FileId, "
+ " (select f.skey from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload1' and fr.refId = ff.id order by fr.id desc limit 1) as uploadFileSkey, "
+ " (select f.id from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload2' and fr.refId = ff.id order by fr.id desc limit 1) as upload2FileId, "
+ " (select f.skey from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload2' and fr.refId = ff.id order by fr.id desc limit 1) as upload2FileSkey, "
+ " ff.id, "
+ " ff.templateId, "
+ " ff.fileId, "
@@ -2411,15 +2422,27 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
HSBCFIN(fieldName, fieldValue, commonField, acroForm);
}

if ("MLB03S".equals(formCode)) {
MLB03S(fieldName, fieldValue, commonField, acroForm);
}

if("MLFNA_EN".equals(formCode)){
MLFNA_EN(fieldName, fieldValue, commonField, acroForm);
}

if("MLFNA_CHI".equals(formCode)){
MLFNA_EN(fieldName, fieldValue, commonField, acroForm);
}
//

if ("SLFNA_EN".equals(formCode)) {
SLFNA_EN(fieldName, fieldValue, commonField, acroForm);
}

if ("SLFNA_CHI".equals(formCode)) {
SLFNA_EN(fieldName, fieldValue, commonField, acroForm);
}

if ("SLAPP".equals(formCode)) {
SLAPP(fieldName, fieldValue, commonField, acroForm);
}
@@ -2428,10 +2451,6 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
HSBCA31(fieldName, fieldValue, commonField, acroForm);
}

if ("MLB03S".equals(formCode)) {
MLB03S(fieldName, fieldValue, commonField, acroForm);
}

if ("SLGII".equals(formCode)) {
SLGII(fieldName, fieldValue, commonField, acroForm);
@@ -2599,7 +2618,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
/* Page7 Start */
case "fill_11_7" -> commonField.setInsuranceCompany1_1(fieldValue);
case "fill_11_7_1" -> commonField.setInsuranceCompany1_2(fieldValue);
case "fill_11_7_2" -> commonField.setInsuranceCompany1_3(fieldValue);
//case "fill_11_7_2" -> commonField.setInsuranceCompany1_3(fieldValue);
case "fill_12_7_1" -> {
commonField.getOthers().put("insuranceSumInsured1_1", fieldValue);

@@ -2630,7 +2649,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito

case "fill_13_7" -> commonField.setInsuranceCompany2_1(fieldValue);
case "fill_13_7_1" -> commonField.setInsuranceCompany2_2(fieldValue);
case "fill_13_7_2" -> commonField.setInsuranceCompany2_3(fieldValue);
//case "fill_13_7_2" -> commonField.setInsuranceCompany2_3(fieldValue);
case "fill_14_7_1" -> {
commonField.getOthers().put("insuranceSumInsured2_1", fieldValue);

@@ -2662,7 +2681,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito

case "fill_15_7" -> commonField.setInsuranceCompany3_1(fieldValue);
case "fill_15_7_1" -> commonField.setInsuranceCompany3_2(fieldValue);
case "fill_15_7_2" -> commonField.setInsuranceCompany3_3(fieldValue);
//case "fill_15_7_2" -> commonField.setInsuranceCompany3_3(fieldValue);
case "fill_16_7_1" -> {
commonField.getOthers().put("insuranceSumInsured3_1", fieldValue);

@@ -3046,9 +3065,104 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
case "Check Box17" -> commonField.setFna_c2f_50(fieldValue);
/* Page5 End */

}
}

private void MLB03S(String fieldName, String fieldValue, CommonField commonField,PDAcroForm acroForm){
switch (fieldName) {
/* Page1 Start */
case "SurName1" -> commonField.setFirstName(fieldValue);
case "GivenName1" -> commonField.setGivenName(fieldValue);
case "ChineseName1" -> commonField.setNameChi(fieldValue);

case "male" -> commonField.setGenderMale(fieldValue);
case "female" -> commonField.setGenderFemale(fieldValue);

case "DD1" -> commonField.setDdDateOfBirth(fieldValue);
case "MM1" -> commonField.setMmDateOfBirth(fieldValue);
case "YYYY1" -> commonField.setYyyyDateOfBirth(fieldValue);

case "hk" -> {
if("Yes".equals(fieldValue))
commonField.setPlaceOfBirth("Hong Kong");
}
case "macau" -> {
if("Yes".equals(fieldValue))
commonField.setPlaceOfBirth("Macau");
}
case "Field_LocationA1" -> commonField.setPlaceOfBirth(fieldValue);
case "Field_LocationB1" -> commonField.setPlaceOfBirth(fieldValue);

case "ID1" -> commonField.setIdCard(fieldValue);

case "Nationality1" -> commonField.setCountryOfCitizenship(fieldValue);
case "Company1" -> commonField.setCompanyName(fieldValue);
case "BusinessNature1" -> commonField.setCompanyNature1(fieldValue);
case "BusinessNature2" -> commonField.setCompanyNature2(fieldValue);
case "Occupation1" -> commonField.setOccupation(fieldValue);
case "JobNature1" -> commonField.setOccupationTitle(fieldValue);

//Income1 = IDA commonField.getIncomeSalary() + commonField.getIncomeBonus() ??? beware of it may have , and english P.A. or even USD
case "Room1" -> commonField.getOthers().put("crAddressRoom", fieldValue);
case "Floor1" -> commonField.getOthers().put("crAddressFloor", fieldValue);
case "Block1" -> commonField.getOthers().put("crAddressBlock", fieldValue);
case "Building1" -> commonField.getOthers().put("crAddressBuilding", fieldValue);
case "Street1" -> commonField.getOthers().put("crAddressStreet", fieldValue);
case "City1" -> commonField.getOthers().put("crAddressCity", fieldValue);
case "District1" -> commonField.getOthers().put("crAddressDistrict", fieldValue);
case "Country1" -> commonField.getOthers().put("crAddressCountry", fieldValue);
case "PostalCode1" -> commonField.getOthers().put("crAddressPostalCode", fieldValue);
case "Checkbox_Y" -> commonField.setTobarccoYes(fieldValue);
case "Checkbox_N" -> commonField.setTobarccoNo(fieldValue);
/* Page1 End */
/* Page2 Start */
case "Room3" -> commonField.getOthers().put("corAddressRoom", fieldValue);
case "Floor3" -> commonField.getOthers().put("corAddressFloor", fieldValue);
case "Block3" -> commonField.getOthers().put("corAddressBlock", fieldValue);
case "Building3" -> commonField.getOthers().put("corAddressBuilding", fieldValue);
case "Street3" -> commonField.getOthers().put("corAddressStreet", fieldValue);
case "City3" -> commonField.getOthers().put("corAddressCity", fieldValue);
case "District3" -> commonField.getOthers().put("corAddressDistrict", fieldValue);
case "Country3" -> commonField.getOthers().put("corAddressCountry", fieldValue);
case "PostalCode3" -> commonField.getOthers().put("corAddressPostalCode", fieldValue);

case "ContactB1" -> commonField.setContactNo(fieldValue);
case "Email" -> commonField.setEmail(fieldValue);
/* Page2 End */
/* Page3 Start */
case "Checkbox_Wealth1" -> commonField.getOthers().put("sourceIncome", fieldValue);
case "Checkbox_Wealth2" -> commonField.getOthers().put("sourceInvestment", fieldValue);
case "Checkbox_Wealth3" -> commonField.getOthers().put("sourceInheritance", fieldValue);
case "Checkbox_Wealth4" -> commonField.getOthers().put("sourceOther", fieldValue);
case "Field_Wealth4" -> commonField.getOthers().put("sourceOtherDesc", fieldValue);
case "Checkbox_EudcationPri" -> commonField.setEduPri(fieldValue);
case "Checkbox_EudcationSec" -> commonField.setEduSec(fieldValue);
case "Checkbox_EudcationPostSec" -> commonField.setEduPostSec(fieldValue);
case "Checkbox_EudcationTer" -> commonField.setEduUni(fieldValue);
/* Page3 End */
/* Page7 Start */
case "Residency1" -> commonField.setTaxResidency1(fieldValue);
case "Residency2" -> commonField.setTaxResidency2(fieldValue);
case "Residency3" -> commonField.setTaxResidency3(fieldValue);
case "TIN1" -> commonField.setTaxPin1(fieldValue);
case "TIN2" -> commonField.setTaxPin2(fieldValue);
case "TIN3" -> commonField.setTaxPin3(fieldValue);
case "ABC1" -> commonField.setTaxReason1(fieldValue);
case "ABC2" -> commonField.setTaxReason2(fieldValue);
case "ABC3" -> commonField.setTaxReason3(fieldValue);
case "Reason1" -> commonField.setTaxReasonB1(fieldValue);
case "Reason2" -> commonField.setTaxReasonB2(fieldValue);
case "Reason3" -> commonField.setTaxReasonB3(fieldValue);
/* Page7 End */
/* Page8 Start */
case "c_DeclartionYes" -> commonField.setReplaceInsuranceYes(fieldValue);
case "c_DeclartionNo" -> commonField.setReplaceInsuranceNo(fieldValue);
/* Page8 End */
}
}

@@ -3372,7 +3486,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
case "4_1_name1_1" -> commonField.setInsuranceCompany1_1(fieldValue);
case "4_1_name1_2" -> commonField.setInsuranceCompany1_2(fieldValue);
case "4_1_name1_3" -> commonField.setInsuranceCompany1_3(fieldValue);
//case "4_1_name1_3" -> commonField.setInsuranceCompany1_3(fieldValue);
case "4_1_year1" -> commonField.setInsuranceYear1(fieldValue);
case "4_1_currency1" -> commonField.setInsuranceCurrency1(fieldValue);
case "4_1_sum1_1" -> commonField.getOthers().put("insuranceSumInsured1_1", fieldValue);
@@ -3423,7 +3537,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
case "4_1_name2_1" -> commonField.setInsuranceCompany2_1(fieldValue);
case "4_1_name2_2" -> commonField.setInsuranceCompany2_2(fieldValue);
case "4_1_name2_3" -> commonField.setInsuranceCompany2_3(fieldValue);
//case "4_1_name2_3" -> commonField.setInsuranceCompany2_3(fieldValue);
case "4_1_year2" -> commonField.setInsuranceYear2(fieldValue);
case "4_1_currency2" -> commonField.setInsuranceCurrency2(fieldValue);
case "4_1_sum2_1" -> commonField.getOthers().put("insuranceSumInsured2_1", fieldValue);
@@ -3474,7 +3588,7 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito

case "4_1_name3_1" -> commonField.setInsuranceCompany3_1(fieldValue);
case "4_1_name3_2" -> commonField.setInsuranceCompany3_2(fieldValue);
case "4_1_name3_3" -> commonField.setInsuranceCompany3_3(fieldValue);
//case "4_1_name3_3" -> commonField.setInsuranceCompany3_3(fieldValue);
case "4_1_year3" -> commonField.setInsuranceYear3(fieldValue);
case "4_1_currency3" -> commonField.setInsuranceCurrency3(fieldValue);
case "4_1_sum3_1" -> commonField.getOthers().put("insuranceSumInsured3_1", fieldValue);
@@ -3664,104 +3778,6 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
}
}

private void MLB03S(String fieldName, String fieldValue, CommonField commonField,PDAcroForm acroForm){
switch (fieldName) {
/* Page1 Start */
case "SurName1" -> commonField.setFirstName(fieldValue);
case "GivenName1" -> commonField.setGivenName(fieldValue);
case "ChineseName1" -> commonField.setNameChi(fieldValue);

case "male" -> commonField.setGenderMale(fieldValue);
case "female" -> commonField.setGenderFemale(fieldValue);

case "DD1" -> commonField.setDdDateOfBirth(fieldValue);
case "MM1" -> commonField.setMmDateOfBirth(fieldValue);
case "YYYY1" -> commonField.setYyyyDateOfBirth(fieldValue);

case "hk" -> {
if("Yes".equals(fieldValue))
commonField.setPlaceOfBirth("Hong Kong");
}
case "macau" -> {
if("Yes".equals(fieldValue))
commonField.setPlaceOfBirth("Macau");
}
case "Field_LocationA1" -> commonField.setPlaceOfBirth(fieldValue);
case "Field_LocationB1" -> commonField.setPlaceOfBirth(fieldValue);

case "ID1" -> commonField.setIdCard(fieldValue);

case "Nationality1" -> commonField.setCountryOfCitizenship(fieldValue);
case "Company1" -> commonField.setCompanyName(fieldValue);
case "BusinessNature1" -> commonField.setCompanyNature1(fieldValue);
case "BusinessNature2" -> commonField.setCompanyNature2(fieldValue);
case "Occupation1" -> commonField.setOccupation(fieldValue);
case "JobNature1" -> commonField.setOccupationTitle(fieldValue);

//Income1 = IDA commonField.getIncomeSalary() + commonField.getIncomeBonus() ??? beware of it may have , and english P.A. or even USD
case "Room1" -> commonField.getOthers().put("crAddressRoom", fieldValue);
case "Floor1" -> commonField.getOthers().put("crAddressFloor", fieldValue);
case "Block1" -> commonField.getOthers().put("crAddressBlock", fieldValue);
case "Building1" -> commonField.getOthers().put("crAddressBuilding", fieldValue);
case "Street1" -> commonField.getOthers().put("crAddressStreet", fieldValue);
case "City1" -> commonField.getOthers().put("crAddressCity", fieldValue);
case "District1" -> commonField.getOthers().put("crAddressDistrict", fieldValue);
case "Country1" -> commonField.getOthers().put("crAddressCountry", fieldValue);
case "PostalCode1" -> commonField.getOthers().put("crAddressPostalCode", fieldValue);
case "Checkbox_Y" -> commonField.setTobarccoYes(fieldValue);
case "Checkbox_N" -> commonField.setTobarccoNo(fieldValue);
/* Page1 End */
/* Page2 Start */
case "Room3" -> commonField.getOthers().put("corAddressRoom", fieldValue);
case "Floor3" -> commonField.getOthers().put("corAddressFloor", fieldValue);
case "Block3" -> commonField.getOthers().put("corAddressBlock", fieldValue);
case "Building3" -> commonField.getOthers().put("corAddressBuilding", fieldValue);
case "Street3" -> commonField.getOthers().put("corAddressStreet", fieldValue);
case "City3" -> commonField.getOthers().put("corAddressCity", fieldValue);
case "District3" -> commonField.getOthers().put("corAddressDistrict", fieldValue);
case "Country3" -> commonField.getOthers().put("corAddressCountry", fieldValue);
case "PostalCode3" -> commonField.getOthers().put("corAddressPostalCode", fieldValue);

case "ContactB1" -> commonField.setContactNo(fieldValue);
case "Email" -> commonField.setEmail(fieldValue);
/* Page2 End */
/* Page3 Start */
case "Checkbox_Wealth1" -> commonField.getOthers().put("sourceIncome", fieldValue);
case "Checkbox_Wealth2" -> commonField.getOthers().put("sourceInvestment", fieldValue);
case "Checkbox_Wealth3" -> commonField.getOthers().put("sourceInheritance", fieldValue);
case "Checkbox_Wealth4" -> commonField.getOthers().put("sourceOther", fieldValue);
case "Field_Wealth4" -> commonField.getOthers().put("sourceOtherDesc", fieldValue);
case "Checkbox_EudcationPri" -> commonField.setEduPri(fieldValue);
case "Checkbox_EudcationSec" -> commonField.setEduSec(fieldValue);
case "Checkbox_EudcationPostSec" -> commonField.setEduPostSec(fieldValue);
case "Checkbox_EudcationTer" -> commonField.setEduUni(fieldValue);
/* Page3 End */
/* Page7 Start */
case "Residency1" -> commonField.setTaxResidency1(fieldValue);
case "Residency2" -> commonField.setTaxResidency2(fieldValue);
case "Residency3" -> commonField.setTaxResidency3(fieldValue);
case "TIN1" -> commonField.setTaxPin1(fieldValue);
case "TIN2" -> commonField.setTaxPin2(fieldValue);
case "TIN3" -> commonField.setTaxPin3(fieldValue);
case "ABC1" -> commonField.setTaxReason1(fieldValue);
case "ABC2" -> commonField.setTaxReason2(fieldValue);
case "ABC3" -> commonField.setTaxReason3(fieldValue);
case "Reason1" -> commonField.setTaxReasonB1(fieldValue);
case "Reason2" -> commonField.setTaxReasonB2(fieldValue);
case "Reason3" -> commonField.setTaxReasonB3(fieldValue);
/* Page7 End */
/* Page8 Start */
case "c_DeclartionYes" -> commonField.setReplaceInsuranceYes(fieldValue);
case "c_DeclartionNo" -> commonField.setReplaceInsuranceNo(fieldValue);
/* Page8 End */
}
}

private void SLGII(String fieldName, String fieldValue, CommonField commonField,PDAcroForm acroForm){
switch (fieldName) {
/* Page1 Start */
@@ -3892,13 +3908,13 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito
/* Page6 Start */
case "4_1_name1_1" -> commonField.setInsuranceCompany1_1(fieldValue);
case "4_1_name1_2" -> commonField.setInsuranceCompany1_2(fieldValue);
case "4_1_name1_3" -> commonField.setInsuranceCompany1_3(fieldValue);
//case "4_1_name1_3" -> commonField.setInsuranceCompany1_3(fieldValue);
case "4_1_name2_1" -> commonField.setInsuranceCompany2_1(fieldValue);
case "4_1_name2_2" -> commonField.setInsuranceCompany2_2(fieldValue);
case "4_1_name2_3" -> commonField.setInsuranceCompany2_3(fieldValue);
//case "4_1_name2_3" -> commonField.setInsuranceCompany2_3(fieldValue);
case "4_1_name3_1" -> commonField.setInsuranceCompany3_1(fieldValue);
case "4_1_name3_2" -> commonField.setInsuranceCompany3_2(fieldValue);
case "4_1_name3_3" -> commonField.setInsuranceCompany3_3(fieldValue);
//case "4_1_name3_3" -> commonField.setInsuranceCompany3_3(fieldValue);
case "4_1_year1" -> commonField.setInsuranceYear1(fieldValue);
case "4_1_year2" -> commonField.setInsuranceYear2(fieldValue);
case "4_1_year3" -> commonField.setInsuranceYear3(fieldValue);
@@ -4274,4 +4290,27 @@ public class PdfService extends AbstractBaseEntityService<Pdf, Long, PdfReposito

return d;
}

public Map<String, Object> getFilledFormPdf(Long id) {
StringBuilder sql = new StringBuilder("SELECT"
+ " ff.fileId, "
+ " f.skey as fileSkey, "

+ " (select f.id from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload1' and fr.refId = ff.id order by fr.id desc limit 1) as upload1FileId, "
+ " (select f.id from file_ref fr left join file f on fr.fileId = f.id where fr.refType = 'upload2' and fr.refId = ff.id order by fr.id desc limit 1) as upload2FileId, "
+ " ff.id, "
+ " ff.remarks, "
+ " f.filename, "
+ " t.remarks AS formCode, "
+ " fb.bytes AS blobValue "
+ " FROM filled_form ff "
+ " LEFT JOIN file f ON f.id = ff.fileId "
+ " LEFT JOIN file_blob fb ON f.id = fb.fileId "
+ " LEFT JOIN template t ON t.id = ff.templateId "
+ " WHERE ff.deleted = FALSE "
+ " AND ff.id = :id "
);
return jdbcDao.queryForMap(sql.toString(), Map.of("id", id)).orElse(null);
}
}

+ 185
- 14
src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java ファイルの表示

@@ -1,18 +1,20 @@
package com.ffii.lioner.modules.lioner.pdf.web;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Optional;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
@@ -22,21 +24,18 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ffii.core.response.DataRes;
import com.ffii.core.response.RecordsRes;
import com.ffii.core.utils.CriteriaArgsBuilder;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import com.ffii.core.exception.NotFoundException;
import com.ffii.core.utils.Params;
import com.ffii.lioner.modules.lioner.pdf.req.UpdatePdfReq;
import com.ffii.lioner.modules.lioner.entity.FileBlob;
import com.ffii.lioner.modules.lioner.pdf.service.PdfMergeService;
import com.ffii.lioner.modules.lioner.pdf.service.PdfService;
import com.ffii.lioner.modules.lioner.service.FileService;
import com.itextpdf.io.source.ByteArrayOutputStream;

import jakarta.servlet.http.HttpServletRequest;


@RestController
@@ -44,6 +43,13 @@ import com.ffii.lioner.modules.lioner.pdf.service.PdfService;
@CrossOrigin(origins = "", allowedHeaders = "")

public class PdfController {
protected final Log logger = LogFactory.getLog(getClass());

@Autowired
private PdfMergeService pdfMergeService;

@Autowired
private FileService fileService;

private PdfService pdfService;

@@ -129,4 +135,169 @@ public class PdfController {
response.put("message", "Form data received and processed successfully.");
return ResponseEntity.ok(response);
}

@GetMapping("/merge-pdf")
public String mergePdf() {
try {
pdfMergeService.mergePdfs();
return "PDFs merged successfully";
} catch (IOException e) {
return "Error merging PDFs: " + e.getMessage();
}
}

//this if for upload signiture 1 for PDF form merging later
@PostMapping("/upload1")
public ResponseEntity<Map<String, String>> upload1(@RequestParam("file") MultipartFile file, @RequestParam Long refId, @RequestParam String refType) {
try {
MultipartFile[] files = new MultipartFile[1];
files[0] = file;
fileService.saveOrUpdate(files, refId, refType);

Map<String, String> response = new HashMap<>();
response.put("message", "File uploaded and processed successfully.");
return ResponseEntity.ok(response);
} catch (Exception ex) {
Map<String, String> errorBody = new HashMap<>();
errorBody.put("message", "File upload failed: " + ex.getMessage());
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(errorBody);
}
}


@GetMapping(value = "/download-ff/{id}", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getMergedPdfByFilledFormId(@PathVariable Long id) throws IOException {
logger.info("XXXXXXXXXXXXXXX getMergedPdfByFilledFormId START XXXXXXXXXXXXXX");
// --- 1. Fetch Data & Set up Variables ---
Map<String, Object> d = pdfService.getFilledFormPdf(id);
String formCode = (String) d.get("formCode");
String filename = formCode + "-" + id + ".pdf";

Long fileId = Optional.ofNullable(d.get("fileId"))
.map(val -> ((Integer) val).longValue())
.orElse(null);

Long upload1FileId = Optional.ofNullable(d.get("upload1FileId"))
.map(val -> ((Integer) val).longValue())
.orElse(null);

// Safely retrieve byte arrays using Optional chaining (prevents NullPointerExceptions)
byte[] pdfBytes = Optional.ofNullable(fileId)
.flatMap(fileService::findFileBlobByFileId)
.map(FileBlob::getBytes)
.orElse(null);

// Only fetch upload1 if needed (or if it's generally required)
byte[] pdfUpload1Bytes = Optional.ofNullable(upload1FileId)
.flatMap(fileService::findFileBlobByFileId)
.map(FileBlob::getBytes)
.orElse(null);

// Check if the primary file is missing
if (pdfBytes == null || pdfBytes.length == 0) {
logger.info("Both null:");
return ResponseEntity.notFound().build();
}

// --- 2. PDF Merging and Processing ---
byte[] finalPdfBytes = new byte[0];
logger.info("pdfBytes:" + pdfBytes.length);
logger.info("pdfUpload1Bytes:" + pdfUpload1Bytes.length);
logger.info("formCode:" + formCode);

finalPdfBytes = pdfMergeService.mergePdfsItext7(formCode, pdfBytes, pdfUpload1Bytes);
// --- 4. Build ResponseEntity ---
HttpHeaders headers = new HttpHeaders();
// Use attachment for download, or inline for display in browser
headers.setContentDispositionFormData("attachment", filename);
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentLength(finalPdfBytes.length);

return new ResponseEntity<>(finalPdfBytes, headers, HttpStatus.OK);
}

/*

@GetMapping(value = "/download-ff", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getMergedPdfByFilledFormId(@PathVariable Long id) throws IOException {
Map<String, Object> d = pdfService.getFilledFormPdf(id);
//get the filled form id
;
byte[] pdfBytes = fileService.findFileBlobByFileId((Long)d.get("fileId")).orElse(null).getBytes();
byte[] pdfUpload1Bytes = fileService.findFileBlobByFileId((Long)d.get("upload1FileId")).orElse(null).getBytes();
PDDocument outputDoc = new PDDocument();

logger.info("formCode:" + d.get("formCode"));
if("IDA".equals(d.get("formCode"))){
//page 9 is the sig page, so remove page 9 of pdf and merge the upload1
//PDDocument sourceDoc = Loader.loadPDF(pdfBytes);
try (PDDocument sourceDoc = Loader.loadPDF(pdfBytes)) {
int pageCount = sourceDoc.getNumberOfPages();

logger.info("pageCount:" + pageCount);
} catch (IOException e) {
// This ONLY catches standard IO exceptions. It might not catch the S.O.E.
logger.info("IOException:" + e.toString());
}

try (PDDocument upload1Doc = Loader.loadPDF(pdfUpload1Bytes)) {
// ...
} catch (IOException e) {
// This ONLY catches standard IO exceptions. It might not catch the S.O.E.
logger.info("IOException:" + e.toString());
}
// You can now work with the document, e.g., get the number of pages
for (int i = 0; i < sourceDoc.getNumberOfPages(); i++) {
PDPage page = sourceDoc.getPage(i);
outputDoc.addPage(page);
}

for (int i = 0; i < upload1Doc.getNumberOfPages(); i++) {
PDPage page = upload1Doc.getPage(i);
outputDoc.addPage(page);
}
}

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

public byte[] convertPdfDocumentToBytes(PDDocument doc) throws IOException {
// 1. Create a stream to hold the PDF's bytes in memory
// Use try-with-resources to ensure the stream is automatically closed.
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
// 2. Save the PDDocument content into the ByteArrayOutputStream
// This process writes the entire PDF structure (objects, XRef, etc.)
doc.save(baos);
// 3. Convert the content of the stream to a byte array
return baos.toByteArray();
} finally {
// 4. Important: Close the PDDocument to release resources
if (doc != null) {
doc.close();
}
}
}


}

読み込み中…
キャンセル
保存