Thymeleaf+Spring Boot:如何通过点击事件更新object标签的PDF内容?
实现步骤拆解
这需求很常见,我来给你拆解成前端(Thymeleaf页面)和后端(Spring Boot接口)两部分,一步步搞定:
一、前端页面修改(Thymeleaf)
首先补全你的页面代码,加上日期选择器、触发按钮,以及用来显示PDF的object标签,再用JavaScript处理点击事件:
<div class="row"> <div class="col"> <h5 style="color:red;">Seleziona data</h5> <div class="input-group input-group-prepend col-4"> <span class="input-group-text">Data</span> <!-- 日期输入框,默认输出yyyy-MM-dd格式,和后端解析兼容 --> <input type="date" id="selectedDate" class="form-control"> <button id="loadPdfBtn" class="btn btn-primary">Carica PDF</button> </div> </div> </div> <div class="row mt-3"> <div class="col"> <!-- PDF预览容器,初始提示浏览器不支持的情况 --> <object id="pdfViewer" type="application/pdf" width="100%" height="600px"> <p>Il tuo browser non supporta la visualizzazione di PDF. <a href="#" id="pdfDownloadLink">Scarica il file</a></p> </object> </div> </div> <script> document.getElementById('loadPdfBtn').addEventListener('click', function() { const selectedDate = document.getElementById('selectedDate').value; // 先校验日期是否选择 if (!selectedDate) { alert('Per favore, seleziona una data prima!'); return; } // 构建后端接口URL,带上日期参数 const pdfApiUrl = `/api/pdf/generate?date=${selectedDate}`; // 更新object标签的data属性,浏览器会自动请求并渲染新PDF const pdfViewer = document.getElementById('pdfViewer'); // 先清空旧数据避免缓存问题,再设置新URL pdfViewer.data = ''; setTimeout(() => { pdfViewer.data = pdfApiUrl; }, 100); // 同时更新下载链接(可选) document.getElementById('pdfDownloadLink').href = pdfApiUrl; }); </script>
二、后端Spring Boot接口实现
接下来写一个Controller接口,接收日期参数,生成(或获取)PDF文件,然后以字节流的形式返回给前端:
1. 先添加PDF生成依赖(以iText为例)
如果是Maven项目,在pom.xml里加入:
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
2. 编写PDF生成Controller
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.io.ByteArrayOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfWriter; @RestController @RequestMapping("/api/pdf") public class PdfGenerationController { @GetMapping("/generate") public ResponseEntity<byte[]> generatePdfForDate(@RequestParam("date") String dateString) { // 解析前端传递的日期参数(yyyy-MM-dd格式) LocalDate selectedDate = LocalDate.parse(dateString, DateTimeFormatter.ISO_LOCAL_DATE); // 生成PDF内容(这里是示例,你可以替换成从数据库取数据、自定义模板等逻辑) ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); Document pdfDocument = new Document(); try { PdfWriter.getInstance(pdfDocument, pdfOutputStream); pdfDocument.open(); // 添加PDF内容 pdfDocument.add(new Paragraph("Report PDF - Data: " + selectedDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")))); pdfDocument.add(new Paragraph("\nContenuto del report generato dinamicamente...")); pdfDocument.close(); } catch (DocumentException | IOException e) { e.printStackTrace(); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } // 设置响应头,告诉浏览器这是可在线预览的PDF HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentType(MediaType.APPLICATION_PDF); // "inline"表示在线预览,改成"attachment"就是强制下载 responseHeaders.setContentDispositionFormData("inline", "report_" + dateString + ".pdf"); return new ResponseEntity<>(pdfOutputStream.toByteArray(), responseHeaders, HttpStatus.OK); } }
三、关键注意事项
- 浏览器兼容性:部分旧浏览器对
object标签的PDF支持不佳,可以换成<embed>标签,用法和object完全一致。 - 缓存问题:如果遇到PDF不更新的情况,可以在URL后加随机参数,比如
pdfApiUrl + "&t=" + new Date().getTime(),避免浏览器缓存旧文件。 - 日期格式:HTML的
date输入框默认输出yyyy-MM-dd格式,后端用LocalDate.parse直接解析即可,不用额外转换。 - 权限控制:如果需要登录才能访问PDF接口,Spring Boot的会话机制会自动携带Cookie,无需额外处理。
内容的提问来源于stack exchange,提问作者Droide
相关产品推荐
相关产品推荐

