Angular/Spring Boot Rest API下载Word文档
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,POI生成Word文档使用POI XWPF生成Word文档,引入POI: org.apache.poi poi-ooxml 4.1.0项目中经常从Word模板生成文档,下面示例演示了
千家信息网最后更新 2025年12月02日Angular/Spring Boot Rest API下载Word文档
POI生成Word文档
使用POI XWPF生成Word文档,引入POI:
org.apache.poi poi-ooxml 4.1.0 项目中经常从Word模板生成文档,下面示例演示了替换文档内容的方法。模版中要替换的内容以${}标识,调用XWPFRun.setText()方法更新文档。
import org.apache.poi.xwpf.usermodel.XWPFDocument;import org.apache.poi.xwpf.usermodel.XWPFParagraph;import org.apache.poi.xwpf.usermodel.XWPFRun;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.util.List;import java.util.Map;public final class XWPFDocumentUtils { private XWPFDocumentUtils() { } public static byte[] replaceDocument(String path, Map fields) throws IOException { try (XWPFDocument doc = new XWPFDocument(new FileInputStream(path))) { for (XWPFParagraph paragraph : doc.getParagraphs()) { if (!paragraph.getText().contains("${")) { continue; } replaceParagraph(paragraph, fields); } try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { doc.write(out); return out.toByteArray(); } } } private static void replaceParagraph(XWPFParagraph paragraph, Map fields) { for (Map.Entry field : fields.entrySet()) { String find = "${" + field.getKey() + "}"; if (!paragraph.getText().contains(find)) { continue; } replaceText(paragraph, find, field.getValue()); } } private static void replaceText(XWPFParagraph paragraph, String key, String value) { List runs = paragraph.getRuns(); for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String text = run.text(); if (text.contains("${") || (text.contains("$") && runs.get(i + 1).text().startsWith("{"))) { StringBuilder builder = new StringBuilder(text); while (!text.contains("}")) { text = runs.get(i + 1).text(); builder.append(text); paragraph.removeRun(i + 1); } text = builder.toString(); run.setText(text.contains(key) ? text.replace(key, value) : text, 0); } } }} Spring Boot Rest API
Rest API
调用replaceDocument()方法生成word文档,如要在Rest API中定义文件名称,使用ResponseEntity并增加header,否则可以直接返回byte[]。
@GetMapping("/api/doc/{heroName}")public ResponseEntity getDocument(@PathVariable String heroName) { try { Map fields = new HashMap<>(); fields.put("hero_name", heroName); fields.put("create_date", "2019年6月"); byte[] bytes = XWPFDocumentUtil.replaceDocument("template/hero.docx", fields); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=hero.docx"); return ResponseEntity.ok().headers(headers).body(bytes); } catch (Exception e) { throw new XWPFDocumentException(e.getMessage()); }} CORS
配置CORS的ExposedHeaders,否则前台不能读取"Content-Disposition":
@BeanCorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); SecurityProperties.Cors cors = config.getCors(); configuration.setAllowedMethods(Arrays.asList("*")); configuration.setAllowedHeaders(Arrays.asList("Accept","Accept-Encoding","Accept-Language","Authorization","Connection","Content-Type","Host","Origin","Referer","User-Agent","X-Requested-With")); configuration.setExposedHeaders(Arrays.asList("Content-Disposition")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source;}Test
测试使用exchange方法,设置header APPLICATION_OCTET_STREAM:
import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.boot.test.web.client.TestRestTemplate;import org.springframework.http.*;import org.springframework.test.context.junit4.SpringRunner;import java.util.Arrays;import static org.assertj.core.api.Assertions.assertThat;@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class HeroesApplicationTests { @Autowired private TestRestTemplate restTemplate; @Test public void getDocumentSuccess() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM)); HttpEntity entity = new HttpEntity<>(headers); ResponseEntity response = restTemplate.exchange("/api/doc/jason", HttpMethod.GET, entity, byte[].class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); }} Angular下载文档
可以使用链接直接访问REST URL下载文档,若项目启用了JWT Token验证,则必须使用HttpClient的get方法。
本文使用了FileSaver.js保存文档,开始之前先安装:
npm install --save file-saver然后在tsconfig.json中添加:
"paths": { "file-saver": [ "node_modules/file-saver/dist/FileSaver.js" ]}下载方法:
import * as fs from 'file-saver';downloadDocument() { this.httpClient.get('yourUrl', {observe: 'response', responseType: 'blob'}).subscribe(response => { fs.saveAs(response.body, this.getFilename(response.headers)); });}private getFilename(headers: HttpHeaders): string { const disposition = headers.get('Content-Disposition'); if (!disposition || disposition.indexOf('filename=') < 0) { return ''; } return disposition.substr(disposition.indexOf('filename=') + 9);}或
downloadDocument() { this.httpClient.get('yourUrl', {responseType: 'blob'}).subscribe(data => { fs.saveAs(data, 'yourFilename'); });}参考文档
Excel File - Download from SpringBoot RestAPI + Apache POI + MySQL
Apache POI Word Tutorial
文档
方法
生成
内容
项目
前台
名称
文件
标识
模板
模版
示例
链接
前先
参考
更新
测试
演示
配置
验证
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
dbo数据库
安徽发展软件开发行业标准
数据库服务器技术
荣耀50有什么先进的网络技术
服务器的名字
机构树的数据库表设计图
提高服务器安全的方法
pubg登录服务器
电脑显示服务器连接异常就掉线
贵州网络安全防疫知识
软件开发魔典怎么样
4399美食大战老鼠服务器列表
昭通辰庆互联网科技有限公司
软件开发项目调研提纲
宁波北辰软件开发有限公司
软件开发对人体有危害吗
dayz服务器教程
创造与魔法合并的服务器
服务器双网口做级联
数据库驱动和sql
服务器一般使用怎样的网线口
信息处理技术员考数据库吗
微机课软件开发网址
软考软件开发攻略
软件开发环境三个部分
网络安全知识发言材料存在问题
服务器 内存条
linux怎么看数据库实例
普陀区参考数据库销售诚信服务
洛阳能源万谦网络技术支持