Angular / Spring Boot Rest API to download a Word document

POI Word Document

Use POI XWPF generate a Word document, the introduction of POI:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.0</version>
</dependency>

Projects often generate Word document from a template, the following example demonstrates a method to replace the contents of the document. Template to replace the contents of $ {} identification, call XWPFRun.setText () method updates the document.

package org.iata.caims.util;

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;

import static org.springframework.util.StringUtils.isEmpty;

public class XWPFDocumentUtils {
    public static byte[] replaceDocument(String path, Map<String, String> fields) throws IOException {
        try (XWPFDocument doc = new XWPFDocument(new FileInputStream(path))) {
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
                String paragraphText = paragraph.getText();
                if (!paragraphText.contains("${")) {
                    continue;
                }

                for (Map.Entry<String, String> field : fields.entrySet()) {
                    String find = "${" + field.getKey() + "}";
                    if (!paragraphText.contains(find)) {
                        continue;
                    }

                    List<XWPFRun> runs = paragraph.getRuns();
                    for (int i = 0; i < runs.size(); i++) {
                        XWPFRun run = runs.get(i);
                        String text = run.text();

                        if (isEmpty(text)) {
                            continue;
                        }

                        if (text.contains("${") || (text.contains("$") && runs.get(i + 1).text().startsWith("{"))) {
                            while (!text.contains("}")) {
                                text += runs.get(i + 1).text();
                                paragraph.removeRun(i + 1);
                            }
                            run.setText(text.contains(find) ? text.replace(find, field.getValue()) : text, 0);
                        }
                    }
                }
            }

            try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                doc.write(out);
                return out.toByteArray();
            }
        }
    }
}

Spring Boot Rest API

Call replaceDocument () method to generate word documents, such as to define the file name in the Rest API using ResponseEntity and increase the header, otherwise it can return byte [].

@GetMapping("/api/doc/{heroName}")
public ResponseEntity<byte[]> getDocument(@PathVariable String heroName) {
    try {
        Map<String, String> 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());
    }
}

ExposedHeaders CORS configuration, or the front desk can not read "Content-Disposition":

@Bean
CorsConfigurationSource 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;
}

Angular download documents

You can use the link to download the document directly access the REST URL, if the project enabled JWT Token authentication, you must use the get method of HttpClient.
As used herein, the FileSaver.js save the document, install Before you begin:

npm install --save file-saver

Then tsconfig.json added:

"paths": {
  "file-saver": [
    "node_modules/file-saver/dist/FileSaver.js"
  ]
}

Download method:

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);
}

or

downloadDocument() {
  this.httpClient.get('yourUrl', {responseType: 'blob'}).subscribe(data => {
    fs.saveAs(data, 'yourFilename');
  });
}

Reference Documents

Excel File – Download from SpringBoot RestAPI + Apache POI + MySQL
Apache POI Word Tutorial

Guess you like

Origin blog.51cto.com/7308310/2412183