iT邦幫忙

0

Day 11 - 資料動態渲染:後端 Service 結合 Thymeleaf 樣板引擎

  • 分享至 

  • xImage
  •  

今日目標
在 Spring Boot 中撰寫業務邏輯 Service,將資料庫儲存的病患健檢紀錄與檢驗項目動態包裝為 Thymeleaf Context,交由樣板引擎生成最終的完整 HTML 報表字串。

核心概念:前後端邏輯的完美交匯
在前幾天的實作中,我們的 ReportPreviewController 都是用 List.of() 自行模擬假資料。
但在真實的醫療系統中,當醫師點擊「產出報表」時,系統必須:

  1. 根據病患 ID 從資料庫(PatientRepository)撈出真實的個人資料。
  2. 從資料庫(或檢驗系統)撈出該病患對應的檢驗項目數據。
  3. 透過 Thymeleaf 的 SpringTemplateEngine,將這些動態資料「灌」進我們精心設計的 health_report.html 樣板中,轉化為一長串精美的 HTML 原始碼。
    今天我們就要把這段資料流徹底打通!

核心程式碼

  1. LabItemEntity.java(檢驗項目實體)
    java
@Data
@Entity
@Table(name = "lab_items")
public class LabItemEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long patientId; // 關聯哪一位病患
    private String itemName;
    private String resultValue;
    private String unit;
    private String referenceRange;
    private boolean isAbnormal;
}

此 Entity 負責對應資料庫的 lab_items 表格。透過 patientId 欄位與病患身分建立關聯,並利用 isAbnormal 布林值來標記該項檢驗結果是否超出正常參考範圍,作為後續前端樣板動態標紅的依據。

  1. TemplateRenderService.java(樣板渲染核心服務)
public String renderReportHtml(Long patientId) {
    // 1. 從資料庫撈取病患資料
    Patient patient = patientRepository.findById(patientId)
            .orElseThrow(() -> new RuntimeException("找不到該病患資料"));

    // 2. 從資料庫撈取該病患的檢驗項目
    List<LabItemEntity> items = labItemRepository.findByPatientId(patientId);

    // 3. 建立 Thymeleaf Context 並綁定變數
    Context context = new Context();
    context.setVariable("patientName", patient.getName());
    context.setVariable("patientId", patient.getIdNumber());
    context.setVariable("labItems", items);

    // 4. 指定渲染 health_report 樣板,回傳最終 HTML 字串
    return templateEngine.process("health_report", context);
}

是後端資料流與前端樣板交匯的橋樑。它透過 Repository 撈出真實資料後,利用 Thymeleaf 的 Context 物件將資料封裝,最後呼叫 templateEngine.process() 將動態資料「灌」進 HTML 檔中,產出完整的原始碼字串。

測試與心得
重新啟動伺服器後,發現瀏覽器上直接顯示了一大串結構完整的 HTML 原始碼!這串 HTML 正是從資料庫抓出「張心懷」的資料與異常檢驗數值後,透過 Thymeleaf 引擎即時拼裝出來的。

明天我們將要把這串 HTML 透過 Java 21 的 HttpClient 送往我們在 Day 3 架好的 Gotenberg 容器,正式產出第一份加密前的 PDF 檔案!


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言