前言
excel下载工具类
代码示例
- 批量下载(无弹框,直接保存);需要文件地址
转载:http://blog.csdn.net/liu19890121liu/article/details/39229389
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileDownload {
public static void main(String[] args) {
// 需要压缩的文件--包括文件地址和文件名
String []path ={"D:\\1.txt",
"D:\\2.txt"};
// 要生成的压缩文件地址和文件名称
String desPath = "C:\\Users\\Administrator\\Desktop\\DownLoad.zip";
File zipFile = new File(desPath);
ZipOutputStream zipStream = null;
FileInputStream zipSource = null;
BufferedInputStream bufferStream = null;
try {
// 构造最终压缩包的输出流
zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
for(int i =0;i<path.length;i++){
File file = new File(path[i]);
// 将需要压缩的文件格式化为输入流
zipSource = new FileInputStream(file);
// 压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样
ZipEntry zipEntry = new ZipEntry(file.getName());
// 定位该压缩条目位置,开始写入文件到压缩包中
zipStream.putNextEntry(zipEntry);
// 输入缓冲流
bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
int read = 0;
// 创建读写缓冲区
byte[] buf = new byte[1024 * 10];
while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1)
{
zipStream.write(buf, 0, read);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭流
try {
if(null != bufferStream) bufferStream.close();
if(null != zipStream) zipStream.close();
if(null != zipSource) zipSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- == 单个文件下载(有弹框)==
转载:http://blog.csdn.net/zhxtpray/article/details/38942463
public void download(HttpServletResponse response) {
// 所要下载的文件路径,从数据库中查询得到,当然也可以直接写文件路径,如:C:\\Users\\Administrator\\Desktop\\csv\\号码_utf8_100.csv
String filePath = this.queueService.getCsvFilePathById(id);
try {
File file = new File(filePath);
// 得到文件名
String fileName = filePath.substring(filePath.lastIndexOf(File.separator)+1);
// 把文件名按UTF-8取出并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。
fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");
// 告诉浏览器输出内容为流;设置了头文件才会有弹框;
response.setContentType("application/octet-stream");
// Content-Disposition中指定的类型是文件的扩展名,
// 并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,
// 文件以filename的值命名,保存类型以Content中设置的为准。
// 注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。
response.addHeader("Content-Disposition", "attachment;filename="+fileName);
String len = String.valueOf(file.length());
response.setHeader("Content-Length", len);//设置内容长度
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[1024];
int n;
while((n=in.read(b))!=-1){
out.write(b, 0, n);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
- 多文件打包下载,通用于任何文件。下载时,占用内存
ps:该方式使用到了hutool
- 第一步
/**
* 生成zip
*
* @param response
* @param data
*/
public static void generatorZip(HttpServletResponse response, List<ZipFileContentDto> data) {
try {
// 创建字节数组输出流对象
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 创建zip输出流对象,同时字节数组输出流传入构造函数。
// ps:根据下面的代码实现,可以看出在循环的时候,除了把data数据流写入到zip,同时也把一部分数据写入到了byteArrayOutputStream里面
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
// 通过循环把data里面的数据转成流,写入到zip里面
for (ZipFileContentDto zipFileContentDto : data) {
// 填充数据
excelStreamAddZipOutputStream(zipOutputStream, zipFileContentDto.getFileName(), zipFileContentDto.getFileTitle(), zipFileContentDto.getRows());
}
// 关闭zip输出流
zipOutputStream.closeEntry();
zipOutputStream.close();
// 创建字节数组的集合
List<byte[]> bytelist = new ArrayList<>();
// 把在上面循环中放入的字节数组取出来,放到一个新的集合里面
bytelist.add(byteArrayOutputStream.toByteArray());
// 关闭字节数组
byteArrayOutputStream.close();
// 多个数组合并为一个数组
byte[] bs = BytesToZip.bytesCombine(bytelist);
// 设置浏览器显示的内容类型为Zip
response.setContentType("application/zip");
// 通过response获取ServletOutputStream对象(out)
response.getOutputStream().write(bs);
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (Exception e) {
e.printStackTrace();
}
}
- 第二步
/**
* excel流添加到zip输出流
*
* @param zipOutputStream zip压缩文件输出流
* @param fileName 文件名称
* @param fileTitle 文件标题
* @param rows 当前文件数据
*/
public static void excelStreamAddZipOutputStream(ZipOutputStream zipOutputStream,
String fileName,
String fileTitle,
List<Map<String, Object>> rows) {
try {
// 创建字节数组输出流对象
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 获取excel写入对象
ExcelWriter writer = ExcelUtil.getWriter();
// 设置标题
writer.merge(rows.get(0).size() - 1, fileTitle);
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 把excel文件流输出到字节数组
writer.flush(byteArrayOutputStream, true);
// 设置下一个条目的名称(所谓条目名称,即子文件名称)
zipOutputStream.putNextEntry(new ZipEntry(fileName));
// 从当前字节数组输出流中获取字节数组
byte[] bytes = byteArrayOutputStream.toByteArray();
// 把字节数组写入到当前zip输出流(个人感觉就是写入到上面新增的条目里面了)
zipOutputStream.write(bytes);
// 清空当前缓冲区
byteArrayOutputStream.flush();
// 关闭输出流
byteArrayOutputStream.close();
writer.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
- 第三部
/**
* zip文件内容对象
*/
@Data
@Accessors(chain = true)
public static class ZipFileContentDto implements Serializable {
/**
* 单个excel数据。因为生成excel文件流也是通过hutool工具生成的,所以此处数据结构和它一样。
* 单个rows就是一个excel文件
*/
private List<Map<String, Object>> rows;
/**
* 文件名称;格式:a.xls;后缀对应生成方式:ExcelUtil.getWriter()
*/
private String fileName;
/**
* 文件标题
*/
private String fileTitle;
}
rows示例
官网:https://hutool.cn/docs/#/poi/Excel%E7%94%9F%E6%88%90-ExcelWriter
/**
* 设置rows
*
* @param data
* @return
*/
public static List<Map<String, Object>> setRows(List<WorkLogsDto> data){
List<Map<String, Object>> rows = new ArrayList<>();
if(!CollectionUtils.isEmpty(data)){
for (WorkLogsDto item : data) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("序列", item.getWorkLogId());
map.put("机构名称", item.getShortName());
map.put("部门", item.getDeptname());
map.put("姓名", item.getCreateDispname());
map.put("日期", item.getWorkDay());
map.put("开始时间", item.getStartDate());
map.put("结束时间", item.getEndDate());
map.put("工作内容", item.getContentLabelNames());
map.put("评价", item.getAvgScoreLabel());
map.put("心得", getExperience(item));
map.put("状态", item.getStatus() ? "已完成" : "未提交");
map.put("部门月度评分", item.getScore() == null ? 0 : item.getScore());
map.put("结束时间", item.getEndDate());
rows.add(map);
}
}
return rows;
}