SpringBoot文件下载(Zip & Xml)
1、 Zip
java-controller
/** * 下载某一个主模板下所有的子模板 * @param topProtocol top主模板id * @return */ @GetMapping(value = "downLoadXmlZip") @ApiOperation(value = "根据topProtocol获取模板zip", notes = "获取某一个protocol的xml文本") public void downLoadXmlZip(@NotNull(message = "根据topProtocol获取模板zip") Long topProtocol, HttpServletResponse response){ try { // 调用 sfProtocolService 下载 XML 文件 sfProtocolService.downLoadXmlZip(topProtocol, response); } catch (Exception e) { e.printStackTrace(); } }
java-Service
void downLoadXmlZip(Long topProtocol, HttpServletResponse response) throws IOException;
@Override public void downLoadXmlZip(Long topProtocol, HttpServletResponse response) throws IOException { // 获取全部 List<SfProtocolEntity> downloadList = sfProtocolService.getParentAndChildListIdName(topProtocol); List<Path> files = new ArrayList<>(); downloadList.forEach(item -> { SfFilePathEntity sfFilePathEntity = sfFilePathService.getOne(new LambdaQueryWrapper<SfFilePathEntity>() .eq(SfFilePathEntity::getProtocolId, item.getId())); files.add(Paths.get(sfFilePathEntity.getPath())); }); String fileName = "模板文件.zip"; // 设置相应头 response.setContentType("application/zip"); // 解决文件乱码 FileUtils.setAttachmentResponseHeader(response,fileName); // 压缩多个文件到zip文件中,并且响应给客户端 try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) { for (Path file : files) { try (InputStream inputStream = Files.newInputStream(file)) { zipOutputStream.putNextEntry(new ZipEntry(file.getFileName().toString())); StreamUtils.copy(inputStream, zipOutputStream); zipOutputStream.flush(); } } } }
java-utils
package cn.datax.service.data.metadata.util; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class FileUtils extends org.apache.commons.io.FileUtils { /** * 下载文件名重新编码 * * @param response 响应对象 * @param realFileName 真实文件名 * @return */ public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { String percentEncodedFileName = percentEncode(realFileName); StringBuilder contentDispositionValue = new StringBuilder(); contentDispositionValue.append("attachment; filename=") .append(percentEncodedFileName) .append(";") .append("filename*=") .append("utf-8''") .append(percentEncodedFileName); response.setHeader("Content-disposition", contentDispositionValue.toString()); } /** * 百分号编码工具方法 * * @param s 需要百分号编码的字符串 * @return 百分号编码后的字符串 */ public static String percentEncode(String s) throws UnsupportedEncodingException { String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); return encode.replaceAll("\\+", "%20"); } }
vue-api
// 下载某一个主模板下所有的子模板 export function downLoadXmlZip(id) { return request({ url: '/data/metadata/stepForm/downLoadXmlZip?topProtocol=' + id, method: 'get', responseType: 'blob', headers:{ 'Content-Type': 'application/zip'} }) }
vue-componet
downLoadStepForm(id){ downLoadXmlZip(id).then(response => { const blob = new Blob([response], { type: 'application/zip' }); const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = '模板文件.zip'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }) .catch(error => { console.error('Error downloading ZIP file:', error); }); },
result
2、 Xml
java-controller
/** * 返回blob * @param protocol top主模板id * @return */ @GetMapping("downLoadXml") @ApiOperation(value = "返回blob", notes = "返回blob") public void downLoadXml(@NotNull(message = "protocol不能是空") Long protocol, HttpServletResponse response){ try { // 调用 sfProtocolService 下载 XML 文件 sfProtocolService.downLoadXml(protocol, response); } catch (Exception e) { e.printStackTrace(); } }
java-Service
void downLoadXml(Long protocol, HttpServletResponse response) throws UnsupportedEncodingException;
/** * 下载单个xml * @param protocol * @param response */ @Override public void downLoadXml(Long protocol, HttpServletResponse response) throws UnsupportedEncodingException { SfFilePathEntity sfFilePathEntity = sfFilePathService.getOne(new LambdaQueryWrapper<SfFilePathEntity>() .eq(SfFilePathEntity::getProtocolId, protocol)); String filePath = sfFilePathEntity.getPath(); Path path = Paths.get(filePath); String fileName = path.getFileName().toString(); // 设置响应头 response.setContentType(MediaType.APPLICATION_XML_VALUE); FileUtils.setAttachmentResponseHeader(response,fileName); // 将文件内容写入响应的输出流 try (InputStream inputStream = Files.newInputStream(new File(filePath).toPath())) { FileCopyUtils.copy(inputStream, response.getOutputStream()); response.getOutputStream().flush(); } catch (IOException e) { throw new RuntimeException(e); } }
java-utils
package cn.datax.service.data.metadata.util; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class FileUtils extends org.apache.commons.io.FileUtils { /** * 下载文件名重新编码 * * @param response 响应对象 * @param realFileName 真实文件名 * @return */ public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { String percentEncodedFileName = percentEncode(realFileName); StringBuilder contentDispositionValue = new StringBuilder(); contentDispositionValue.append("attachment; filename=") .append(percentEncodedFileName) .append(";") .append("filename*=") .append("utf-8''") .append(percentEncodedFileName); response.setHeader("Content-disposition", contentDispositionValue.toString()); } /** * 百分号编码工具方法 * * @param s 需要百分号编码的字符串 * @return 百分号编码后的字符串 */ public static String percentEncode(String s) throws UnsupportedEncodingException { String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); return encode.replaceAll("\\+", "%20"); } }
vue-api
//返回blob 下载某一个xml export function downLoadXml(id) { return request({ url: '/data/metadata/stepForm/downLoadXml?protocol=' + id, method: 'get', responseType: 'blob', headers:{ 'Content-Type': 'application/xml'} }) }
vue-componet
downLoad(row) { let id = row.id let name = row.label downLoadXml(id).then(response => { const blob = new Blob([response], {type: 'application/xml'}); const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = `${name}.xml`; document.body.appendChild(link); link.click(); document.body.removeChild(link); }) }, // 将blob中文本解析出来 initXmlData(id) { this.previewType = "xml"; downLoadXml(id).then(res => { const blob = new Blob([res], { type: 'text/plain' }); this.blobToString(blob).then((result) => { console.log("result::",result); // "test" this.previewResult = result console.log("this.previewResultthis.previewResult::",this.previewResult) }); }) },
result