Spring Boot + FreeMarker 實(shí)現(xiàn)動(dòng)態(tài)Word文檔導(dǎo)出功能
Spring Boot + FreeMarker 實(shí)現(xiàn)動(dòng)態(tài)Word文檔導(dǎo)出
在現(xiàn)代企業(yè)應(yīng)用中,文檔自動(dòng)化生成是一項(xiàng)提升工作效率的重要功能。Spring Boot與FreeMarker的組合,為開(kāi)發(fā)者提供了一個(gè)強(qiáng)大的平臺(tái),可以輕松實(shí)現(xiàn)動(dòng)態(tài)Word文檔的導(dǎo)出。本文將指導(dǎo)你如何使用Spring Boot與FreeMarker模板引擎,創(chuàng)建一個(gè)簡(jiǎn)單的應(yīng)用,用于根據(jù)數(shù)據(jù)庫(kù)數(shù)據(jù)動(dòng)態(tài)生成Word文檔并下載。
技術(shù)棧簡(jiǎn)介
- Spring Boot:簡(jiǎn)化Spring應(yīng)用初始搭建以及開(kāi)發(fā)過(guò)程的框架,提供了快速開(kāi)發(fā)、運(yùn)行、部署的解決方案。
- FreeMarker:一款用Java編寫的模板引擎,特別適合生成HTML、XML、RTF、Java源代碼等文本格式的輸出,當(dāng)然也包括Word文檔。
準(zhǔn)備工作
1. 創(chuàng)建Spring Boot項(xiàng)目
使用Spring Initializr創(chuàng)建一個(gè)新的Spring Boot項(xiàng)目,記得勾選Thymeleaf(雖然我們用FreeMarker,但Thymeleaf依賴也會(huì)帶來(lái)Spring MVC的支持,便于后續(xù)配置)。
2. 添加FreeMarker依賴
在pom.xml中加入FreeMarker的依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
3. 配置FreeMarker
在application.properties中配置FreeMarker的路徑。
spring.freemarker.template-loader-path=classpath:/templates/
創(chuàng)建FreeMarker模板
在src/main/resources/templates目錄下,創(chuàng)建一個(gè)名為document.ftl的FreeMarker模板文件,內(nèi)容如下:
<!DOCTYPE html>
<html> <head> <#assign document = { "title": "動(dòng)態(tài)Word文檔", "content": [ {"header": "章節(jié)一", "text": "這里是章節(jié)一的內(nèi)容..."}, {"header": "章節(jié)二", "text": "這里是章節(jié)二的內(nèi)容..."} ] }> </head> <body> <h1>${document.title}</h1> <#list document.content as section> <h2>${section.header}</h2> <p>${section.text}</p> </#list> </body> </html>編寫Controller
創(chuàng)建一個(gè)Controller來(lái)處理請(qǐng)求,讀取模板并填充數(shù)據(jù),最后將Word文檔返回給用戶下載。
java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import freemarker.template.Configuration; import freemarker.template.Template; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity;
import java.io.IOException; import java.util.HashMap; import java.util.Map;
@RestController public class DocumentController {
@Autowired
private Configuration freemarkerConfig;
@GetMapping("/export")
public ResponseEntity<byte[]> exportDocument() throws IOException {
// 假設(shè)數(shù)據(jù)是從數(shù)據(jù)庫(kù)獲取的,這里為了簡(jiǎn)化直接構(gòu)造示例數(shù)據(jù)
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("title", "來(lái)自數(shù)據(jù)庫(kù)的標(biāo)題");
dataModel.put("content", getDatabaseContent());
Template template = freemarkerConfig.getTemplate("document.ftl");
String processedHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel);
// 將HTML轉(zhuǎn)換為Word文檔(此處簡(jiǎn)化處理,實(shí)際可能需要使用Apache POI等庫(kù))
byte[] wordBytes = convertHtmlToWord(processedHtml);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", "document.docx");
return new ResponseEntity<>(wordBytes, headers, HttpStatus.OK);
}
private List<Map<String, String>> getDatabaseContent() {
// 此處模擬從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)
return Arrays.asList(
Map.of("header", "數(shù)據(jù)庫(kù)章節(jié)一", "text", "數(shù)據(jù)庫(kù)內(nèi)容一"),
Map.of("header", "數(shù)據(jù)庫(kù)章節(jié)二", "text", "數(shù)據(jù)庫(kù)內(nèi)容二")
);
}
// 簡(jiǎn)化的HTML轉(zhuǎn)Word邏輯,實(shí)際應(yīng)用中可能需要更復(fù)雜的轉(zhuǎn)換過(guò)程
private byte[] convertHtmlToWord(String html) {
// 這里省略了HTML轉(zhuǎn)Word的具體實(shí)現(xiàn),可以使用第三方庫(kù)如Apache POI等
return html.getBytes(); // 這只是示例,實(shí)際返回的應(yīng)該是Word文檔的字節(jié)流
}
}總結(jié)
通過(guò)上述步驟,我們使用Spring Boot與FreeMarker成功構(gòu)建了一個(gè)簡(jiǎn)單的應(yīng)用,能夠根據(jù)模板和數(shù)據(jù)庫(kù)數(shù)據(jù)動(dòng)態(tài)生成Word文檔并提供下載。實(shí)際應(yīng)用中,你可能需要引入額外的庫(kù)(如Apache POI等)來(lái)更精確地控制Word文檔的樣式和結(jié)構(gòu),以及更高效地處理HTML到Word的轉(zhuǎn)換過(guò)程。此外,確保處理好模板的安全性,避免注入攻擊等問(wèn)題。
到此這篇關(guān)于Spring Boot + FreeMarker 實(shí)現(xiàn)動(dòng)態(tài)Word文檔導(dǎo)出的文章就介紹到這了,更多相關(guān)Spring Boot FreeMarker Word文檔導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入探究一下Java中不同的線程間數(shù)據(jù)通信方式
這篇文章主要來(lái)和大家一起深入探究一下Java中不同的線程間數(shù)據(jù)通信方式,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-04-04
java線程池實(shí)戰(zhàn)應(yīng)用步驟詳解
這篇文章主要介紹了java線程池實(shí)戰(zhàn)應(yīng)用小結(jié),包括線程池的創(chuàng)建方式,本文給大家分享兩種方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2025-04-04
Java 遞歸查詢部門樹(shù)形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐
本文主要介紹了Java 遞歸查詢部門樹(shù)形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Java8新特性之精簡(jiǎn)的JRE詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之精簡(jiǎn)的JRE詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
聊聊SpringBoot的@Scheduled的并發(fā)問(wèn)題
這篇文章主要介紹了聊聊SpringBoot的@Scheduled的并發(fā)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
idea 實(shí)現(xiàn)縱列選擇和大小寫轉(zhuǎn)換操作
這篇文章主要介紹了idea 實(shí)現(xiàn)縱列選擇和大小寫轉(zhuǎn)換操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
Java實(shí)現(xiàn)的基于socket通信的實(shí)例代碼
Java實(shí)現(xiàn)的基于socket通信的實(shí)例代碼,需要的朋友可以參考一下2013-03-03

