Get the App
SLTechnology News&Howtos  ›  Internet Technology  › 

Angular/Spring Boot Rest API downloads Word documents

Shulou Source: shulou.com Published: 2022-06-03 03:17:07 09月14日 Update

POI generates Word documents

Use POI XWPF to generate Word documents and introduce POI:

Org.apache.poi poi-ooxml 4.1.0

Documents are often generated from Word templates in a project, and the following example demonstrates how to replace the contents of a document. The content to be replaced in the template is identified by ${}, and the XWPFRun.setText () method is called to update the document.

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 APIRest 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');});} reference documentation

Excel File-Download from SpringBoot RestAPI + Apache POI + MySQL

Apache POI Word Tutorial

Tags: Document method build content project foreground name file logo template template example link first reference update test demonstration configuration verification Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Shulou Information Linux Huawei vpn Apple