[update] Integrate ultrasound report generation with JasperReports in CheckUpPage. Add functionality to scale RTF font sizes for improved printing quality. Update UltrasoundResult class to display reports directly and enhance launch configuration for testing ultrasound print functionality.

This commit is contained in:
Lê Thành Đạt committed 2025-07-07 17:18:40 +07:00
1 parent 75aa04d77f
commit f68533455b
6 files changed
+495 -5

No files matched your search

+7
View File
@@ -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",
@@ -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;
}
}
@@ -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<String, Object> 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);
@@ -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<String, Object> 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();
}
}
}
@@ -0,0 +1,244 @@
<!-- Created with Jaspersoft Studio version 7.0.3.final using JasperReports Library version 7.0.3-41034ca841d452f3305ba55b9042260aaa1ab5dd -->
<jasperReport name="Blank_A4_Landscape" language="java" columnCount="1" pageWidth="842" pageHeight="595" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e7f9ca7e-f0db-48b0-bef9-93be21b3b0a3">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<property name="com.jaspersoft.studio.unit." value="pixel"/>
<property name="com.jaspersoft.studio.unit.pageHeight" value="pixel"/>
<property name="com.jaspersoft.studio.unit.pageWidth" value="pixel"/>
<property name="com.jaspersoft.studio.unit.topMargin" value="pixel"/>
<property name="com.jaspersoft.studio.unit.bottomMargin" value="pixel"/>
<property name="com.jaspersoft.studio.unit.leftMargin" value="pixel"/>
<property name="com.jaspersoft.studio.unit.rightMargin" value="pixel"/>
<property name="com.jaspersoft.studio.unit.columnWidth" value="pixel"/>
<property name="com.jaspersoft.studio.unit.columnSpacing" value="pixel"/>
<parameter name="checkupNote" class="java.lang.String"/>
<parameter name="checkupDate" class="java.lang.String"/>
<parameter name="patientDiagnos" class="java.lang.String"/>
<parameter name="doctorName" class="java.lang.String"/>
<parameter name="medicineDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="serviceDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="supplementDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="name" class="java.lang.String"/>
<parameter name="clinicName" class="java.lang.String"/>
<parameter name="patientAddress" class="java.lang.String"/>
<parameter name="clinicPhone" class="java.lang.String"/>
<parameter name="patientName" class="java.lang.String"/>
<parameter name="patientDOB" class="java.lang.String"/>
<parameter name="clinicAddress" class="java.lang.String"/>
<parameter name="logoImage" class="java.lang.String"/>
<parameter name="barcodeNumber" class="java.lang.String"/>
<parameter name="patientGender" class="java.lang.String"/>
<parameter name="hasMedicines" class="java.lang.Boolean"/>
<parameter name="hasServices" class="java.lang.Boolean"/>
<parameter name="hasSupplements" class="java.lang.Boolean"/>
<parameter name="checkupConclusion" class="java.lang.String"/>
<parameter name="checkupSuggestion" class="java.lang.String"/>
<parameter name="reCheckupDate" class="java.lang.String"/>
<parameter name="image1" class="java.lang.String"/>
<parameter name="image2" class="java.lang.String"/>
<parameter name="image3" class="java.lang.String"/>
<parameter name="image4" class="java.lang.String"/>
<parameter name="image5" class="java.lang.String"/>
<parameter name="numberImage" class="java.lang.Integer"/>
<parameter name="image6" class="java.lang.String"/>
<query language="sql"><![CDATA[]]></query>
<background splitType="Stretch"/>
<title splitType="Stretch"/>
<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>
@@ -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));
}
}