Java中字符串生成文件打包为zip下载
需求
目前有freemarker引擎生成的插值后html字符串数据,现在需求是下载到前端;
需要两种方式下载:一,html单个文件 二,多个文件下载打包成zip下载
话不多说直接上代码
编写工具类
@Slf4j
public class FileDownloadUtils {
@Data
public static class FileVo{
private String fileName;
private String string;
public FileVo(){}
public FileVo(String fileName,String string){
this.fileName=fileName;
this.string=string;
}
}
public static Boolean fileDownLoad(FileVo vo, HttpServletResponse response) {
if(StringUtils.isEmpty(vo.getString())){
throw new ServiceException(500,"[内容为空]");
}
String fileName = vo.getFileName();// 文件名
try {
fileName=new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
OutputStream os=null;
try {
byte[] bytes = vo.getString().getBytes(StandardCharsets.UTF_8);
os= response.getOutputStream();
os.write(bytes);
os.close();
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(500,"[下载失败]");
} finally {
if (null != os) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
/**
* 多个html字符串打包成zip下载
*/
public static void zipFileDownload(Map<String, byte[]> byteList,HttpServletResponse response) {
try {
String fileName = System.currentTimeMillis()+".zip";// .zip名
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
OutputStream outputStream = response.getOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
byteList.forEach((k, v) -> {
//写入一个条目,我们需要给这个条目起个名字,相当于起一个文件名称
try {
zipOutputStream.putNextEntry(new ZipEntry(k));
zipOutputStream.write(v);
} catch (IOException e) {
e.printStackTrace();
log.error("写入文件失败");
}
});
//关闭条目
zipOutputStream.closeEntry();
zipOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
log.error("压缩文件失败");
}
}
}
又是一个小细节
解决在前端显示文件名中文乱码
String fileName = vo.getFileName();// 文件名
try {
fileName=new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
业务层调用方法
先在controller层将response传到service
@GetMapping(value = "/download")
public void download(@RequestParam String id, HttpServletResponse response) {
fileDownloadService.fileDownLoad(id,response);
}
service调用
单个文件下载
FileDownloadUtils.FileVo vo = new FileDownloadUtils.FileVo("filename"+".txt","filebodyString");
FileDownloadUtils.fileDownLoad(vo,response);
多个文件打包zip下载
Map<String, byte[]> map = new HashMap<String, byte[]>();
//String直接getBytes() 就可以获得byte[]数组
map.add("filename"+".txt","filebodyString".getBytes());
FileDownloadUtils.zipFileDownload(map ,response);
END
如果你想知道freemarker在我这个需求中是如何使用的,你可以翻阅上一篇博客
码字不易,如果对你有帮助,请给个三连吧!