将word文件以压缩包的形式,在浏览器下载。实现报错:解压下载的zip文件,显示数据损坏,如图
详细代码如下:
@PostMapping("/exportNewWord")
public AjaxResult exportNewWord(@RequestBody Map<String, Object> params, HttpServletResponse response) {
try {
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
String masterid = params.get("masterid").toString();
String domain = params.get("domain").toString();
Map<String, Object> map = new HashMap<>();
Applysourcepooldetail detailQuery = new Applysourcepooldetail();
detailQuery.setMaterid(Long.valueOf(masterid));
List<Applysourcepooldetail> list = applysourcepooldetailService.selectApplysourcepooldetailList(detailQuery);
if (list.size()>0) {
for (int i = 0; i < list.size(); i++) {
Applysourcepooldetail detail = list.get(i);
if(detail.getInputvalue().contains("</")&&detail.getInputvalue().contains("/>")&&detail.getInputvalue().contains("src=")){
StringBuilder stringBuilder=new StringBuilder(detail.getInputvalue());
if (!stringBuilder.substring(1,7).contains("<img")) {
stringBuilder.insert(3, " ");
}
detail.setInputvalue(stringBuilder.toString());
map.putAll(this.getData(map,detail,domain));
}else{
map.put(detail.getInputfield(), detail.getInputvalue());
}
}
}
WordHtmlGeneratorHelper.handleAllObject(map);
Template t = null;
String filePath="";
if(domain.contains("工业互联网平台服务商")){
filePath = RuoYiConfig.getProfile() + "/template/exportWord.ftl";
configuration.setDirectoryForTemplateLoading(new File(filePath).getParentFile());//模板文件所在路径
t = configuration.getTemplate("exportWord.ftl","UTF-8"); //获取模板文件
}else if(domain.contains("两化融合")){
filePath = RuoYiConfig.getProfile() + "/template/exportLhrhWord.ftl";
configuration.setDirectoryForTemplateLoading(new File(filePath).getParentFile());//模板文件所在路径
t = configuration.getTemplate("exportLhrhWord.ftl","UTF-8"); //获取模板文件
}else if(domain.contains("工业互联网解决方案服务商")){
filePath = RuoYiConfig.getProfile() + "/template/resolveWord.ftl";
configuration.setDirectoryForTemplateLoading(new File(filePath).getParentFile());//模板文件所在路径
t = configuration.getTemplate("resolveWord.ftl","UTF-8"); //获取模板文件
}
File outFile = null;
String fileName = domain;
// s为当前用户桌面所在路径
String tempDir = RuoYiConfig.getProfile()+File.separator;
// fileName = fileName+".doc";
outFile = new File(tempDir,fileName+".doc");
if(!outFile.exists()){
outFile.getParentFile().mkdirs();
}
Writer out = null;
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
t.process(map, out); //将填充数据填入模板文件并输出到目标文件
out.close();
/*压缩*/
String zipFileName = fileName + ".zip";
String zipFilePath = tempDir + zipFileName;
FileOutputStream fos = new FileOutputStream(zipFilePath);
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze = new ZipEntry(fileName+".doc");
zos.putNextEntry(ze);
FileInputStream fis = new FileInputStream(outFile);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
fis.close();
zos.closeEntry();
zos.flush();
zos.close();
fos.close();
//删除服务器上的临时文件
File deleteFile = new File(tempDir+fileName+".doc");
deleteFile.delete();
return AjaxResult.success(zipFilePath);
}catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.success("1");
}
@PostMapping("/downLoadWord")
public void download(@RequestBody Map<String, Object> params,HttpServletResponse response) throws Exception {
String fileUrl = params.get("fileUrl").toString();
File file = new File(fileUrl);
String zipFileName = file.getName();
String zipFilePath = fileUrl;
/**
* 下载
*/
FileInputStream in = null;
OutputStream out = null;
try {
//获取文件名
String filename = zipFileName;
filename = new String(filename.getBytes("iso8859-1"), "UTF-8");
String downloadpath = zipFilePath;
//设置响应头,控制浏览器下载该文件
response.reset();
response.setCharacterEncoding("UTF-8");
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
//读取要下载的文件,保存到文件输入流
in = new FileInputStream(downloadpath);
//创建输出流
out = response.getOutputStream();
//缓存区
byte buffer2[] = new byte[1024];
int len2 = 0;
//循环将输入流中的内容读取到缓冲区中
while ((len2 = in.read(buffer2)) > 0) {
out.write(buffer2, 0, len2);
out.flush();
}
} finally {
//关闭
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
//删除服务器上的临时文件
// File deleteFile = new File(fileUrl);
// deleteFile.delete();
//删除服务器上的压缩文件
File deleteZipFile = new File(zipFilePath);
deleteZipFile.delete();
}
有没有人指导下
后端改完的代码如下:
/*压缩文件*/
String zipFileName = fileName + ".zip";
String zipFilePath = tempDir + zipFileName;
File zipFile = new File(zipFilePath);
if(zipFile.exists()) {
if (zipFile.isDirectory()) {
FileUtils.deleteDirectory(zipFile);
} else {
zipFile.delete();
}
}
FileOutputStream fos = new FileOutputStream(zipFilePath);
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze = new ZipEntry(fileName+".doc");
zos.putNextEntry(ze);
FileInputStream fis = new FileInputStream(outFile);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
fis.close();
zos.flush();
zos.close();
fos.close();
return AjaxResult.success(zipFilePath);
}catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.success("1");
}
@PostMapping("/downLoadWord")
public void download(@RequestBody Map<String, Object> params,HttpServletResponse response) throws Exception {
String fileUrl = params.get("fileUrl").toString();
File file = new File(fileUrl);
String zipFileName = file.getName();
String zipFilePath = fileUrl;
FileInputStream fis = new FileInputStream(file);
// 创建输出流
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[(int) file.length()];
fis.read(buffer);
fis.close();
// 设置响应头
response.setContentType("application/zip");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(zipFileName, "UTF-8"));
out.write(buffer);
out.flush();
out.close();
//删除服务器上的临时文件
File deleteFile = new File(fileUrl);
deleteFile.delete();
}
前端请求代码需要将
将 responseType 设置为 'arraybuffer',以确保正确处理字节数组的响应。
详情可以参考我的创作内容里面有,希望有帮助。
这是我之前写的一个demo,你可以参考借鉴下
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class DownloadFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = "example.docx"; // 文件名,可根据实际情况修改
String filePath = "/path/to/file/example.docx"; // 文件路径,可根据实际情况修改
File file = new File(filePath);
if (file.exists()) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
// 将Word文件打包成zip格式
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
zos.putNextEntry(new ZipEntry(fileName));
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis, 1024);
int read;
while ((read = bis.read(buffer, 0, 1024)) != -1) {
zos.write(buffer, 0, read);
}
zos.closeEntry();
zos.finish();
// 关闭流
bis.close();
fis.close();
response.flushBuffer();
} catch (Exception e) {
e.printStackTrace();
}
} else {
// 如果文件不存在,返回404错误
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().println("File not found.");
}
}
}
步骤:
① 通过response对象获取OutputStream流
② 设置文件ContentType类型,会判断下载文件类型
③ 设置文件头
④ 获取zip的输出流
⑤ 获取文件路径下的所有文件夹及文件
⑥ 获取此目录下的所有文件名与目录名
⑦ 循环读取文件路径集合,获取每一个文件的路径
⑧ 通过文件路径创建文件
⑨ 将每一个文件写入zip文件压缩包内,即进行打包
⑩ 最后刷新缓冲区
代码实现:
/**
* 以zip形式批量下载文件
*
* @param response
* @param downloadName
* @param filePath
*/
public static void MultiFileZipDownload(HttpServletResponse response, String downloadName, String filePath) {
OutputStream outputStream = null;
ZipOutputStream zos = null;
try {
// 通过response对象获取OutputStream流
outputStream = response.getOutputStream();
// 设置文件ContentType类型
response.setContentType("multipart/form-data");
// 设置文件头
response.setHeader("Content-Disposition", "attachment;fileName = " + URLEncoder.encode(downloadName, "UTF-8"));
// 获取zip的输出流
zos = new ZipOutputStream(outputStream);
// 获取文件路径下的所有文件夹及文件
File dirFile = new File(filePath);
// 获取此目录下的所有文件名与目录名
String[] fileList = dirFile.list();
// 循环读取文件路径集合,获取每一个文件的路径
if (fileList != null) {
for (String fp : fileList) {
File file = new File(filePath, fp); // 通过文件路径创建文件
zipFile(file, zos); // 将每一个文件写入zip文件压缩包内,即进行打包
// 刷新缓冲区
response.flushBuffer();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (zos != null) {
zos.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}