最近做了一个excel导出的功能,字段涉及到了图片。但是需求是:导出一个压缩包,压缩包包含一个excel文件和多张图片,图片命名按照业务来区分唯一。
准备工作
实体类
public class MessageDO {
private Integer id;
@ExcelExport("封面")
private String url;
@ExcelExport("标题")
private String title;
@ExcelExport("内容")
private String content;
@ExcelExport("创建时间")
private LocalDateTime createTime;
@ExcelExport("更新时间")
private LocalDateTime updateTime;
//省略get、set方法
//..............
}
测试数据
private List<MessageDO> getList() {
List<MessageDO> messageDOS = new ArrayList<>();
List<String> urlList = Arrays.asList("https://img-blog.csdnimg.cn/20210823171755669.png",
"https://img-blog.csdnimg.cn/20210705113753337.jpeg",
"https://img-blog.csdnimg.cn/20210823085631276.jpeg",
"https://img-blog.csdnimg.cn/20210823085620179.jpeg",
"https://img-blog.csdnimg.cn/2021082308560694.jpeg");
for (int i = 0; i < 5; i++) {
MessageDO messageDO = new MessageDO();
messageDO.setTitle("这个是测试标题" + i);
messageDO.setContent("这个是测试内容" + i);
messageDO.setUrl(urlList.get(i));
messageDO.setCreateTime(LocalDateTime.now());
messageDO.setUpdateTime(LocalDateTime.now());
messageDOS.add(messageDO);
}
return messageDOS;
}
导出我这里使用的是POI,在网上我找到一个使用POI导入导出的文章,写的很不错的哦。
该链接提供了很多方法哦,如我要使用导出功能,直接用里面提供的 ExcelUtils
工具类就好了。
maven依赖
<!-- POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
<scope>compile</scope>
</dependency>
导出excel
由浅入深,首先是实现基本的导出功能。
控制端代码:
/**
* 普通的导出
* @param response
*/
@GetMapping("exportExcel")
public void exportExcel(HttpServletResponse response) {
List<MessageDO> messageDOS = getList();
ExcelUtils.export(response, "导出", messageDOS, MessageDO.class);
}
效果如下:
这就完成了普通的excel导出,是不是很简单。主要是使用了参考链接的工具类。
将图片地址转文件下载打包成压缩文件
一般我们存图片时,都只是存一个url路径。
我这个需求是:根据url路径把图片下载下来,放在一个压缩包里。
这里我提供了一个 FileUtil
工具类。
流程分为三步:
- 通过url链接将文件下载到本地。
- 通过本地路径进行压缩成zip文件。
- 将本地下载好的文件进行删除。
工具类代码如下:
public class FileUtil{
/**
* 通过url下载文件到本地
* @param url 网络地址
* @return
*/
public static File getFileByUrl(String url) {
//对本地文件命名
String fileName = url.substring(url.lastIndexOf("."));
File file = null;
URL urlfile;
InputStream inStream = null;
OutputStream os = null;
try {
file = File.createTempFile(System.currentTimeMillis() + "", fileName);
//下载
urlfile = new URL(url);
inStream = urlfile.openStream();
os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != os) {
os.close();
}
if (null != inStream) {
inStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
/**
* 功能:压缩多个文件,输出压缩后的zip文件流
* @param zipFileName zip文件名
* @param files 导出的文件
* @param imgNameList 文件名
* @param response
* @throws Exception
*/
public static void downZip(String zipFileName, List<File> files, List<String> imgNameList,
HttpServletResponse response) throws Exception {
byte[] buf = new byte[1024];
// 获取输出流
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
ZipOutputStream out = null;
try {
//重点突出
response.reset();
// 不同类型的文件对应不同的MIME类型
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + zipFileName + ".zip");
response.setContentType("application/octet-stream;charset=UTF-8");
//ZipOutputStream类:完成文件或文件夹的压缩
out = new ZipOutputStream(bos);
for (int i = 0; i < files.size(); i++) {
FileInputStream in = new FileInputStream(files.get(i));
//给列表中的文件单独命名
//获取后缀
String imgUrl = files.get(i).getName();
String imgSuffix = imgUrl.substring(imgUrl.lastIndexOf("."));
out.putNextEntry(new ZipEntry(imgNameList.get(i) + imgSuffix));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.closeEntry();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (Objects.nonNull(out)) {
out.flush();
out.close();
}
if (Objects.nonNull(bos)) {
bos.close();
}
//删除文件
delete(files);
}
}
/**
* 本地文件删除
* @param files 多个文件
*/
private static void delete(List<File> files) {
for (File file : files) {
file.delete();
}
}
}
控制端代码:
/**
* 通过多个图片url路径下载zip文件
* @param response
* @throws Exception
*/
@GetMapping("exportImgZip")
public void exportImgZip(HttpServletResponse response) throws Exception {
List<MessageDO> messageDOS = getList();
List<File> fileList = new ArrayList<>();
for (MessageDO messageDO : messageDOS) {
File file = FileUtil.getFileByUrl(messageDO.getUrl());
fileList.add(file);
}
List<String> nameList = Arrays.asList("图片1", "图片2", "图片3", "图片4", "图片5");
FileUtil.downZip("record", fileList, nameList, response);
}
请求访问即可。
解压后就可以看到图片了。
把excel文件和图片文件放在一块打包成zip
需要把excel文件和图片放在一个压缩包里,内容就是:一个excel、多张图片,在一个压缩包文件里。
到了这里,其实根据上面我提供的工具类应该也可以猜出如何实现。因为工具类我也是不断的优化了哦。
思路:
- 导出excel到本地,拿到本地路径。
- 下载图片到本地,拿到本地路径。
- 路径汇总,进行导出zip文件。
这就实现了excel和图片url的导出zip格式文件了。
具体控制端代码如下:
@GetMapping("exportZip")
public void exportZip(HttpServletResponse response) throws Exception {
List<MessageDO> messageDOS = getList();
if (messageDOS.isEmpty()) {
return;
}
String name = System.currentTimeMillis() + ".xlsx";
String fileName = "D:\\" + name;
ExcelUtils1.export1(fileName, "消息", messageDOS, MessageDO.class);
List<File> fileList = new ArrayList<>();
for (MessageDO messageDO : messageDOS) {
File file = FileUtil.getFileByUrl(messageDO.getUrl());
fileList.add(file);
}
File excelFile = new File(fileName);
fileList.add(excelFile);
List<String> nameList = Arrays.asList("图片1", "图片2", "图片3", "图片4", "图片5", "消息excel");
FileUtil.downZip("record", fileList, nameList, response);
}
调用执行:
解压查看:
至此,这个需求就实现了。
细心的小伙伴可能会发现两处地方:1. excel的工具类我使用了 ExcelUtils1.export1
。2. 这里的excel导出时我指定了路径。
其实导出没有改什么内容,就是改为了本地导出,小伙伴可以自行实现即可。
指定了路径是为了获取路径,也可以其他方法哦。
目前就先这样实现了,后面如果有更好的方法可以进行优化。小伙伴们也可以提出想法呀。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/143349.html