diff --git a/.vscode/launch.json b/.vscode/launch.json index 3d256b9..843411f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,13 @@ { "version": "0.2.0", "configurations": [ + { + "type": "java", + "name": "test_ultrasound_print", + "request": "launch", + "mainClass": "BsK.client.ui.component.CheckUpPage.PrintDialog.print_forms.test_ultrasound_print", + "projectName": "ldS_BsK" + }, { "type": "java", "name": "test_print", diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java index 3a951e3..4b7a24c 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java @@ -1373,7 +1373,7 @@ public class CheckUpPage extends JPanel { return; } - UltrasoundResult ultrasoundDialog = new UltrasoundResult( + UltrasoundResult ultrasoundResult = new UltrasoundResult( checkupIdField.getText(), customerLastNameField.getText() + " " + customerFirstNameField.getText(), dobPicker.getJFormattedTextField().getText(), @@ -1381,14 +1381,14 @@ public class CheckUpPage extends JPanel { customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), (String) doctorComboBox.getSelectedItem(), datePicker.getJFormattedTextField().getText(), - getRtfContentAsString(), + TextUtils.scaleRtfFontSize(getRtfContentAsString()), conclusionField.getText(), suggestionField.getText(), selectedImagesForPrint, printType, templateTitle ); - ultrasoundDialog.createDialog(mainFrame); + ultrasoundResult.showDirectJasperViewer(); break; } } diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java index aaeda0d..1c7c003 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java @@ -26,6 +26,17 @@ import lombok.extern.slf4j.Slf4j; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; +// --- JasperReports Imports --- +import net.sf.jasperreports.engine.JREmptyDataSource; +import net.sf.jasperreports.engine.JasperCompileManager; +import net.sf.jasperreports.engine.JasperFillManager; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.xml.JRXmlLoader; +import net.sf.jasperreports.view.JasperViewer; +// --- End JasperReports Imports --- + import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.text.rtf.RTFEditorKit; @@ -39,6 +50,10 @@ import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.*; import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Locale; +import net.sf.jasperreports.engine.JRParameter; @Slf4j public class UltrasoundResult { @@ -79,6 +94,65 @@ public class UltrasoundResult { this.templateTitle = templateTitle; } + public void showDirectJasperViewer() { + try { + Map parameters = new HashMap<>(); + + // Set locale for date/number formatting + parameters.put(JRParameter.REPORT_LOCALE, new Locale("vi", "VN")); + + // Populate all the string parameters + parameters.put("clinicName", LocalStorage.ClinicName != null ? LocalStorage.ClinicName : "Phòng khám BSK"); + parameters.put("clinicAddress", LocalStorage.ClinicAddress != null ? LocalStorage.ClinicAddress : "Địa chỉ phòng khám"); + parameters.put("clinicPhone", LocalStorage.ClinicPhone != null ? LocalStorage.ClinicPhone : "SĐT phòng khám"); + parameters.put("patientName", this.patientName); + parameters.put("patientDOB", this.patientDOB); + parameters.put("patientGender", this.patientGender); + parameters.put("patientAddress", this.patientAddress); + parameters.put("doctorName", this.doctorName); + parameters.put("checkupDate", this.checkupDate); + parameters.put("barcodeNumber", this.checkupId); + + // RTF and plain text content + parameters.put("checkupNote", this.rtfContent); + parameters.put("checkupConclusion", this.conclusion); + parameters.put("checkupSuggestion", this.suggestion); + parameters.put("reCheckupDate", "Tái khám theo lịch hẹn"); // Placeholder, adjust as needed + + // Handle images + int numberOfImages = this.selectedImages.size(); + parameters.put("numberImage", numberOfImages); + + String projectDir = System.getProperty("user.dir"); + parameters.put("logoImage", projectDir + "/src/main/java/BsK/client/ui/assets/icon/logo.jpg"); + + for (int i = 0; i < 6; i++) { + if (i < numberOfImages) { + parameters.put("image" + (i + 1), this.selectedImages.get(i).getAbsolutePath()); + } else { + parameters.put("image" + (i + 1), null); // Pass null for unused image slots + } + } + + // Load and compile the report + String jrxmlPath = projectDir + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml"; + InputStream inputStream = new FileInputStream(new File(jrxmlPath)); + + JasperDesign jasperDesign = JRXmlLoader.load(inputStream); + JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign); + + // Fill the report + JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource()); + + // View the report + JasperViewer.viewReport(jasperPrint, false); + + } catch (Exception e) { + log.error("Error generating or showing JasperReport for Ultrasound", e); + JOptionPane.showMessageDialog(null, "Lỗi khi tạo báo cáo siêu âm: " + e.getMessage(), "Lỗi JasperReport", JOptionPane.ERROR_MESSAGE); + } + } + public void createDialog(JFrame parent) { dialog = new JDialog(parent, "Kết quả siêu âm", true); dialog.setSize(800, 700); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/test_ultrasound_print.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/test_ultrasound_print.java new file mode 100644 index 0000000..4405d24 --- /dev/null +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/test_ultrasound_print.java @@ -0,0 +1,115 @@ +package BsK.client.ui.component.CheckUpPage.PrintDialog.print_forms; + +import net.sf.jasperreports.engine.JREmptyDataSource; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.xml.JRXmlLoader; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.JasperCompileManager; +import net.sf.jasperreports.engine.JasperFillManager; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.view.JasperViewer; +import net.sf.jasperreports.engine.JRParameter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + + +public class test_ultrasound_print { + public static void main(String[] args) { + try { + // 1. Put the data sources into the parameters map + Map parameters = new HashMap<>(); + + // Set locale to Vietnamese for number formatting and dates + parameters.put(JRParameter.REPORT_LOCALE, new Locale("vi", "VN")); + + // 2. Sample data parameters + parameters.put("clinicName", "BSK CLINIC"); + parameters.put("clinicAddress", "123 Main Street, City, Country"); + parameters.put("clinicPhone", "0123-456-789"); + + parameters.put("patientName", "Nguyễn Thị B"); + parameters.put("patientDOB", "20/07/1985"); + parameters.put("patientGender", "Nữ"); + parameters.put("patientAddress", "456 Đường DEF, Phường UVW, Quận 2, TP.HCM"); + parameters.put("patientDiagnos", "Theo dõi thai kỳ tuần 12"); + + parameters.put("doctorName", "BS. Trần Văn C"); + parameters.put("checkupDate", "22/12/2024"); + + // 3. Add the RTF content for the notes, with corrected font sizes. + // RTF font sizes are in "half-points", so \fs24 = 12pt. + String rtfContent = "{\\rtf1\\ansi\n" + + "{\\fonttbl\\f0\\fnil Monospaced;\\f1\\fnil Times New Roman;}\n" + + "{\\colortbl\\red0\\green0\\blue0;\\red51\\green51\\blue51;\\red0\\green0\\blue255;}\n" + + "\n" + + "\\li0\\ri0\\fi0\\f1\\fs28\\i0\\b\\ul0\\cf2 Test\\fs24\\cf1\\par\n" + // Heading at 14pt, main text at 12pt + "\\par\n" + + "dawdawd\\par\n" + + "ad\\par\n" + + " aw\\par\n" + + "daw da\\b0 daw dad aw\\ul d awd awd \\par\n" + + "\\ul0\\tab\\tab\\ul awdawd\\ul0\\par\n" + + "\\li0\\ri0\\fi0\\ul0\\par\n" + + "}"; + parameters.put("checkupNote", rtfContent); + parameters.put("checkupConclusion", "Thai nhi phát triển bình thường, dự kiến sinh trong 3 tháng tới."); // Normal string + parameters.put("checkupSuggestion", "Bổ sung sắt và canxi, tái khám sau 4 tuần."); // Normal string + + + // 4. Add the re-checkup date + parameters.put("reCheckupDate", "ngày 29 tháng 12 năm 2024"); + + // 5. Add barcode number + parameters.put("barcodeNumber", "2024001235"); + + // 6. Set the number of images to display + int numberOfImages = 4; + parameters.put("numberImage", numberOfImages); + + // 7. Add logo image path + String projectDir = System.getProperty("user.dir"); + String logoPath = projectDir + "/src/main/java/BsK/client/ui/assets/icon/logo.jpg"; + parameters.put("logoImage", logoPath); + + // 8. Add paths for the 6 ultrasound images + String imageDir = projectDir + "/img_db/8/"; + String[] imageFiles = { + "IMG_8_20250619_033320.jpg", + "IMG_8_20250619_033621.jpg", + "IMG_8_20250619_033622.jpg", + "IMG_8_20250619_033623.jpg", + "IMG_8_20250628_220921.jpg", + "IMG_9_20250619_034013.jpg" + }; + + for (int i = 0; i < 6; i++) { + if (i < numberOfImages) { + parameters.put("image" + (i + 1), imageDir + imageFiles[i]); + } else { + parameters.put("image" + (i + 1), null); // Pass null for unused image slots + } + } + + // 9. Load and compile the report + String jrxmlPath = projectDir + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml"; + InputStream inputStream = new FileInputStream(new File(jrxmlPath)); + + JasperDesign jasperDesign = JRXmlLoader.load(inputStream); + JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign); + + // 10. Fill the report. Since there's no table, we use an JREmptyDataSource. + JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource()); + + // 11. View the report + JasperViewer.viewReport(jasperPrint, false); // `false` to prevent app exit on close + + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml new file mode 100644 index 0000000..97d14de --- /dev/null +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <pageHeader splitType="Stretch"/> + <columnHeader splitType="Stretch"/> + <detail> + <band height="527" splitType="Stretch"> + <element kind="frame" uuid="2b7ec588-953c-4145-87b7-1d861c272fe0" x="0" y="0" width="400" height="525"> + <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="-5" width="70" height="64"> + <expression><![CDATA[$P{logoImage}]]></expression> + </element> + <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="0" width="300" height="20" fontName="Arial" fontSize="14.0" bold="true"> + <expression><![CDATA["PHÒNG KHÁM " + $P{clinicName}]]></expression> + </element> + <element kind="staticText" uuid="2677daaf-d0fb-40ad-afaa-513efa16055c" x="70" y="20" width="150" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Địa chỉ: ]]></text> + </element> + <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="100" y="20" width="270" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{clinicAddress}]]></expression> + </element> + <element kind="staticText" uuid="1a1405ee-b3e4-4e98-ac08-6818bc29e902" x="70" y="36" width="150" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[SĐT:]]></text> + </element> + <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="100" y="36" width="270" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{clinicPhone}]]></expression> + </element> + <element kind="staticText" uuid="6f89a93f-2d10-4506-baa5-226bdd047b17" x="0" y="59" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> + <text><![CDATA[I.Thông tin]]></text> + </element> + <element kind="staticText" uuid="b8dfca43-cf97-49e5-b58d-4667143dba62" x="0" y="79" width="50" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Họ và tên:]]></text> + </element> + <element kind="staticText" uuid="0a9ca0c8-f2bd-4ade-a025-a6d79c13613f" x="1" y="94" width="80" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Ngày sinh:]]></text> + </element> + <element kind="staticText" uuid="21917ab8-ae07-44c8-ba4e-bc6c4c54b440" x="148" y="94" width="80" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Giới tính:]]></text> + </element> + <element kind="staticText" uuid="bcbb614e-7a4d-48a3-83c2-198e4fb62c5f" x="1" y="109" width="80" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Địa chỉ:]]></text> + </element> + <element kind="staticText" uuid="45fe4be1-9e21-459b-aeee-2efc8354f372" x="221" y="80" width="50" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Bác sĩ:]]></text> + </element> + <element kind="staticText" uuid="f2ff4b17-63cc-4e8c-a3b0-2523f534f21a" x="221" y="94" width="60" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Ngày khám:]]></text> + </element> + <element kind="textField" uuid="1511f53a-b282-41b1-b233-612b6106c07a" x="50" y="79" width="180" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{patientName}]]></expression> + </element> + <element kind="textField" uuid="5bdac267-523d-4931-926b-76233ce9b84d" x="50" y="94" width="98" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{patientDOB}]]></expression> + </element> + <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="186" y="94" width="44" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{patientGender}]]></expression> + </element> + <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="50" y="110" width="200" height="20" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{patientAddress}]]></expression> + </element> + <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="266" y="80" width="134" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{doctorName}]]></expression> + </element> + <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="266" y="94" width="134" height="15" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{checkupDate}]]></expression> + </element> + <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="130" width="49" height="15" fontName="Arial" fontSize="8.0" bold="true" hTextAlign="Left"> + <text><![CDATA[Chuẩn đoán:]]></text> + </element> + <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="51" y="130" width="349" height="26" fontName="Arial" fontSize="8.0"> + <expression><![CDATA[$P{patientDiagnos}]]></expression> + </element> + <element kind="staticText" uuid="b1fa845a-48da-4e45-82b8-8b9d972650f6" x="0" y="156" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> + <text><![CDATA[II.Nội dung]]></text> + </element> + <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="176" width="400" height="348" markup="rtf" fontName="Times New Roman" fontSize="10.0"> + <expression><![CDATA[$P{checkupNote}]]></expression> + </element> + </element> + <element kind="frame" uuid="a72ffc70-007e-43af-a566-b34e6e07b312" x="400" y="0" width="400" height="526"> + <element kind="staticText" uuid="246a04b0-2565-4987-b7f3-dd369703035c" x="0" y="340" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> + <text><![CDATA[III.Kết luận]]></text> + </element> + <element kind="staticText" uuid="c53ef0ab-a702-47fc-9b7c-24307a495b30" x="0" y="430" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> + <text><![CDATA[Đề nghị:]]></text> + </element> + <element kind="staticText" uuid="a38b1187-ddb8-4410-9b52-dc041f894b7b" x="247" y="430" width="96" height="15" fontName="Arial" fontSize="10.0" bold="true" hTextAlign="Center"> + <text><![CDATA[Bác sĩ siêu âm]]></text> + </element> + <element kind="textField" uuid="b548d99d-bedf-4e90-b13b-bdbc763aa974" x="230" y="496" width="132" height="15" fontName="Arial" hTextAlign="Center"> + <expression><![CDATA[$P{doctorName}]]></expression> + </element> + <element kind="textField" uuid="8bca58ab-0958-40fe-8e51-2a39a9d379a5" x="200" y="506" width="200" height="19" pattern="MMMMM dd, yyyy" hTextAlign="Center" vTextAlign="Bottom"> + <expression><![CDATA[new java.text.SimpleDateFormat("'Đức Hoà, ngày ' dd ' tháng ' MM ' năm ' yyyy", new java.util.Locale("vi", "VN")).format(new java.util.Date())]]></expression> + </element> + <element kind="staticText" uuid="c062ce0e-80cb-4e67-a5d9-d85e769c6c4e" x="0" y="511" width="110" height="14" forecolor="#FF0905" fontName="Times New Roman" fontSize="10.0" bold="true"> + <text><![CDATA[Tái khám:]]></text> + </element> + <element kind="textField" uuid="e90ad772-4425-482d-9e75-f2bc66b9084d" x="0" y="358" width="400" height="70" fontName="Times New Roman" fontSize="10.0"> + <expression><![CDATA[$P{checkupConclusion}]]></expression> + </element> + <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-59" y="12" width="60" height="40"> + <component kind="barcode4j:Code128"> + <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> + </component> + </element> + <element kind="staticText" uuid="6a7d5f66-d7cc-481f-9fff-8ece0789b3b4" x="-60" y="2" width="61" height="17" fontName="Arial" fontSize="10.0" bold="false" hTextAlign="Center"> + <text><![CDATA[Mã khám bệnh]]></text> + </element> + <element kind="textField" uuid="d63165c2-19e2-43ad-8a3f-004e00bffdfe" x="0" y="450" width="230" height="55" fontName="Times New Roman" fontSize="10.0"> + <expression><![CDATA[$P{checkupSuggestion}]]></expression> + </element> + <element kind="textField" uuid="cece8e5b-67db-4019-b52a-bf73abae535e" x="46" y="514" width="150" height="15" fontName="Times New Roman" fontSize="8.0"> + <expression><![CDATA[$P{reCheckupDate}]]></expression> + </element> + <element kind="frame" uuid="2f301804-acfa-4b6f-9f52-236c04fd1197" x="0" y="0" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 6]]></printWhenExpression> + <element kind="image" uuid="fe4e4fa7-8b26-4817-ae86-4c147a25abbe" x="83" y="3" width="111" height="113"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + <element kind="image" uuid="9c6302ea-8b4a-48d6-8c42-68313154be77" x="83" y="117" width="111" height="113"> + <expression><![CDATA[$P{image3}]]></expression> + </element> + <element kind="image" uuid="d7d6a47e-a129-4726-80b1-701113d0d9c2" x="83" y="231" width="111" height="113"> + <expression><![CDATA[$P{image5}]]></expression> + </element> + <element kind="image" uuid="7cd3d01b-f3ac-48d1-9749-ab5787497ab9" x="198" y="232" width="111" height="113"> + <expression><![CDATA[$P{image6}]]></expression> + </element> + <element kind="image" uuid="65610203-a91f-4b55-9a33-d6bfb7ffa7a6" x="199" y="117" width="111" height="113"> + <expression><![CDATA[$P{image4}]]></expression> + </element> + <element kind="image" uuid="127b0f54-33e9-43a5-af62-64152d74958f" x="199" y="3" width="111" height="113"> + <expression><![CDATA[$P{image2}]]></expression> + </element> + </element> + <element kind="frame" uuid="58523878-7ef9-46fe-aad7-ee5bd65115aa" x="0" y="1" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 5]]></printWhenExpression> + <element kind="image" uuid="6870ae02-5ee4-40e8-9787-1ad084dc3b7f" x="83" y="3" width="111" height="113"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + <element kind="image" uuid="4216a22f-f20f-4bf1-9e93-79ccc3bbd5c6" x="83" y="117" width="111" height="113"> + <expression><![CDATA[$P{image3}]]></expression> + </element> + <element kind="image" uuid="3069d087-6d97-455c-bb0d-211b0698b54c" x="142" y="231" width="111" height="113"> + <expression><![CDATA[$P{image5}]]></expression> + </element> + <element kind="image" uuid="34187787-d55d-495a-be82-9ff67702211f" x="199" y="117" width="111" height="113"> + <expression><![CDATA[$P{image4}]]></expression> + </element> + <element kind="image" uuid="7b2d4efb-1f35-4c37-80a1-685195e1218e" x="199" y="3" width="111" height="113"> + <expression><![CDATA[$P{image2}]]></expression> + </element> + </element> + <element kind="frame" uuid="33b6f6ef-93e4-4488-a421-08de09b5458c" x="0" y="0" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 4]]></printWhenExpression> + <element kind="image" uuid="1378905c-276f-42ba-9101-18b27ba14e0b" x="28" y="3" width="161" height="165"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + <element kind="image" uuid="58917767-70d5-4822-bb6f-7f5aba6f660e" x="29" y="173" width="161" height="165"> + <expression><![CDATA[$P{image3}]]></expression> + </element> + <element kind="image" uuid="6026efa4-cfd7-4b1d-90be-fe8912eb43c3" x="210" y="3" width="161" height="165"> + <expression><![CDATA[$P{image2}]]></expression> + </element> + <element kind="image" uuid="6c5adc41-f3d7-4e32-997a-e1845d7170c5" x="211" y="173" width="161" height="165"> + <expression><![CDATA[$P{image4}]]></expression> + </element> + </element> + <element kind="frame" uuid="94e66ae9-8863-45e0-9b9d-1a5fb7df84f5" x="0" y="0" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 3]]></printWhenExpression> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <property name="com.jaspersoft.studio.unit.x" value="px"/> + <element kind="image" uuid="3ab88449-e282-41cd-898e-ab91aeef70b9" x="28" y="3" width="161" height="165"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + <element kind="image" uuid="119378b1-674d-457a-bc69-a9823f2160b7" x="121" y="173" width="161" height="165"> + <expression><![CDATA[$P{image3}]]></expression> + </element> + <element kind="image" uuid="8ac7bc19-5ae6-4569-87fb-c9cf72936b50" x="210" y="3" width="161" height="165"> + <expression><![CDATA[$P{image2}]]></expression> + </element> + </element> + <element kind="frame" uuid="935efa61-0cd7-47ab-b7d8-6508a1726537" x="0" y="0" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 2]]></printWhenExpression> + <element kind="image" uuid="8f2957f9-fb76-49d1-94ce-08c723aec7ce" x="121" y="3" width="161" height="165"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + <element kind="image" uuid="f5585019-40b7-4b1b-9c7a-8b10386cf210" x="121" y="173" width="161" height="165"> + <expression><![CDATA[$P{image2}]]></expression> + </element> + </element> + <element kind="frame" uuid="dfa0c283-dbfc-40de-97e0-d1d04db85c96" x="0" y="0" width="400" height="344"> + <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 1]]></printWhenExpression> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <element kind="image" uuid="a7cef70f-1dbe-4d6f-a007-7543bbc2b9b8" x="51" y="30" width="300" height="289"> + <expression><![CDATA[$P{image1}]]></expression> + </element> + </element> + </element> + </band> + </detail> +</jasperReport> diff --git a/src/main/java/BsK/common/util/text/TextUtils.java b/src/main/java/BsK/common/util/text/TextUtils.java index 96d15e6..2507f24 100644 --- a/src/main/java/BsK/common/util/text/TextUtils.java +++ b/src/main/java/BsK/common/util/text/TextUtils.java @@ -1,6 +1,8 @@ package BsK.common.util.text; import java.text.Normalizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public final class TextUtils { @@ -28,16 +30,64 @@ public final class TextUtils { return normalizedText; } + /** + * Scales down the font size definitions in an RTF string by half. + * Finds all occurrences of \fsXX and replaces them with \fs(XX/2). + * This is useful when JTextPane generates RTF with large font sizes + * that need to be normalized for printing with JasperReports. + * + * @param rtfContent The input RTF string. + * @return A new RTF string with font sizes scaled down. + */ + public static String scaleRtfFontSize(String rtfContent) { + if (rtfContent == null) { + return null; + } + + // Regex to find \fs followed by one or more digits. + // The double backslash is needed to create a literal backslash in the regex string. + Pattern pattern = Pattern.compile("\\\\fs(\\d+)"); + Matcher matcher = pattern.matcher(rtfContent); + + StringBuffer sb = new StringBuffer(); + while (matcher.find()) { + try { + // Get the number string from the first capturing group. + String sizeStr = matcher.group(1); + int originalSize = Integer.parseInt(sizeStr); + + // The font size in RTF is in half-points. JTextPane seems to generate + // sizes that are double what is visually represented. Dividing by 2 + // brings it to the expected point size for JasperReports. + int newSize = originalSize / 2; + + // Append the replacement string. We need to escape the backslash for appendReplacement. + matcher.appendReplacement(sb, "\\\\fs" + newSize); + } catch (NumberFormatException e) { + // This should not happen with the given regex, but it's safe to handle. + // In case of an error, just append the original matched string. + matcher.appendReplacement(sb, matcher.group(0)); + } + } + matcher.appendTail(sb); + + return sb.toString(); + } + public static void main(String[] args) { String[] testWords = { "Đạt", "đạt", "Ân", "Ấn", "Lê", "Hồ", "Trần", "Hoàng", "Quốc", "Phạm", "Dũng", "Bạch", "Hạnh", "Cường", "Vỹ" }; - - for (String word : testWords) { System.out.println("Original: " + word + " → Without Accents: " + TextUtils.removeAccents(word)); } + + // Test the new RTF scaling function + System.out.println("\n--- Testing RTF Font Scaling ---"); + String rtfTestString = "{\\rtf1\\ansi{\\fonttbl{\\f0\\fnil Monospaced;}}{\\colortbl;\\red0\\green0\\blue0;}\\pard\\sa200\\sl276\\slmult1\\cf1\\b\\f0\\fs48 Hello World\\fs24 now small\\par}"; + System.out.println("Original RTF: " + rtfTestString); + System.out.println("Scaled RTF: " + scaleRtfFontSize(rtfTestString)); } }