本篇功能是基于Fastdfs文件上传下载功能,作出的将文件打包成一个zip文件下载下来。
    页面效果如下

    image.png

    选择行,点击批量下载按钮,然后就会将所有的文件打包成一个File.zip文件下载下来。解压zip文件夹,就能看到里面包含了下载的所有文件。这种下载方式不局限于xlsx文件,图片格式,文本格式,Java文件等都可以使用这种方式下载下来。

    image.png

    前台代码

    1. //批量下载
    2. function downloadFunction() {
    3. var selected = grid.selectedDataItems();
    4. if(selected.length>0) {
    5. kendo.ui.showConfirmDialog({
    6. title: "提示",
    7. message: "确定要下载?"
    8. }).done(function(event) {
    9. if (event.button == "OK") {
    10. var recpIdList = new Array();
    11. $.each(selected,function(i,v){
    12. recpIdList.push(v.recpId);
    13. });
    14. debugger;
    15. window.location.href="${base.contextPath}/ect/fut/receipt/batchDownload?recpIdList="+recpIdList;
    16. }});
    17. }else{
    18. kendo.ui.showWarningDialog({
    19. message:"请至少选择一行"
    20. })
    21. }
    22. }

    上述是批量下载功能函数,第一步是获取所有行,如果没有选择行,将弹出警告框“请至少选择一行”,第二步,根据所选行去查询文件的服务器路径以及文件名,假如路径都为空,则下载一个空的zip文件,不为空,则将文件打包成zip格式下载。

    后台代码

    1. List<ZipModel> zipModelList = new ArrayList<>();
    2. for (Long recpId : recpIds) {
    3. FutReceipt futReceipt = new FutReceipt();
    4. futReceipt.setRecpId(recpId.floatValue());
    5. futReceipt = futReceiptMapper.selectByPrimaryKey(futReceipt);
    6. //todo:仓单表主键不能为空并且文件不能为空
    7. if (futReceipt.getRecpId() != null && futReceiptMapper.getFilePathById(futReceipt.getRecpId()) != null) {
    8. try {
    9. ZipModel zipModel = new ZipModel();
    10. String filePatch = getFilePatch(futReceipt, requestContext);
    11. //todo:存储文件路径
    12. zipModel.setFilePath(filePatch);
    13. //todo:获取文件后缀,并且将仓单批次作为文件名
    14. zipModel.setFileName(futReceipt.getBatchNum() + filePatch.substring(filePatch.indexOf(".") + 1));
    15. zipModelList.add(zipModel);
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }
    21. //todo:设置打包后的文件名
    22. String fileName = "File.zip";
    23. //todo:临时文件目录,用于存储打包的下载文件
    24. String globalUploadPath = request.getSession().getServletContext().getRealPath("/");
    25. String outFilePath = globalUploadPath + File.separator + fileName;
    26. File file = new File(outFilePath);
    27. //文件输出流
    28. FileOutputStream outStream = new FileOutputStream(file);
    29. //压缩流
    30. ZipOutputStream toClient = new ZipOutputStream(outStream);
    31. //todo:调用通用方法下载fastfds文件,打包成zip文件
    32. ZipUtil.zipFile(zipModelList, toClient);
    33. toClient.close();
    34. outStream.close();
    35. response.setHeader("content-disposition", "attachment;fileName=" + fileName);
    36. //todo:将zip文件下载下来
    37. ZipUtil.downloadZip(file, response);

    实现步骤主要是将所有的fastdfs的文件路径和文件名存储到一个zipModelList对象中。然后先调用通用方法zipFile将这些文件下载下来打包成一个zip文件,放在一个临时存储位置,最后再通过通用方法downloadZip将文件下载下来。

    存储数据对象
    ZipModel.Java

    1. public class ZipModel {
    2. /**
    3. * 文件名
    4. */
    5. private String fileName;
    6. /**
    7. * 文件在fastdfs文件服务器路径
    8. */
    9. private String filePath;
    10. public String getFileName() {
    11. return fileName;
    12. }
    13. public void setFileName(String fileName) {
    14. this.fileName = fileName;
    15. }
    16. public String getFilePath() {
    17. return filePath;
    18. }
    19. public void setFilePath(String filePath) {
    20. this.filePath = filePath;
    21. }
    22. }

    通用生成下载zip方法
    ZipUtil.Java

    1. public class ZipUtil {
    2. private static String IFastdfsService = "hfastdfs.fastdfsfile.service.IFastdfsService";
    3. /**
    4. * 压缩文件列表中的文件
    5. *
    6. * @param files
    7. * @param outputStream
    8. * @throws IOException
    9. * @throws ServletException
    10. */
    11. public static void zipFile(List<ZipModel> files, ZipOutputStream outputStream) throws IOException {
    12. try {
    13. int size = files.size();
    14. //压缩列表中的文件
    15. for (int i = 0; i < size; i++) {
    16. ZipModel zipModel = files.get(i);
    17. try {
    18. zipFile(zipModel, outputStream);
    19. } catch (Exception e) {
    20. continue;
    21. }
    22. }
    23. } catch (Exception e) {
    24. throw e;
    25. }
    26. }
    27. /**
    28. * 将文件写入到zip文件中
    29. *
    30. * @param zipModel
    31. * @param outputstream
    32. * @throws IOException
    33. * @throws ServletException
    34. */
    35. public static void zipFile(ZipModel zipModel, ZipOutputStream outputstream) throws AppException, IOException, MyException {
    36. try {
    37. if (zipModel != null && zipModel.getFilePath() != null && zipModel.getFileName() != null) {
    38. IFastdfsService iFastdfsService = (IFastdfsService) getBean(IFastdfsService);
    39. InputStream bInStream = new ByteArrayInputStream(iFastdfsService.getFile(zipModel.getFilePath()));
    40. ZipEntry entry = new ZipEntry(zipModel.getFileName());
    41. outputstream.putNextEntry(entry);
    42. final int MAX_BYTE = 10 * 1024 * 1024; //最大的流为10M
    43. long streamTotal = 0; //接受流的容量
    44. int streamNum = 0; //流需要分开的数量
    45. int leaveByte = 0; //文件剩下的字符数
    46. byte[] inOutbyte; //byte数组接受文件的数据
    47. streamTotal = bInStream.available(); //通过available方法取得流的最大字符数
    48. streamNum = (int) Math.floor(streamTotal / MAX_BYTE); //取得流文件需要分开的数量
    49. leaveByte = (int) streamTotal % MAX_BYTE; //分开文件之后,剩余的数量
    50. if (streamNum > 0) {
    51. for (int j = 0; j < streamNum; ++j) {
    52. inOutbyte = new byte[MAX_BYTE];
    53. //读入流,保存在byte数组
    54. bInStream.read(inOutbyte, 0, MAX_BYTE);
    55. outputstream.write(inOutbyte, 0, MAX_BYTE); //写出流
    56. }
    57. }
    58. //写出剩下的流数据
    59. inOutbyte = new byte[leaveByte];
    60. bInStream.read(inOutbyte, 0, leaveByte);
    61. outputstream.write(inOutbyte);
    62. outputstream.closeEntry();
    63. bInStream.close(); //关闭
    64. }
    65. } catch (IOException e) {
    66. throw e;
    67. }
    68. }
    69. /**
    70. * 下载打包的文件
    71. *
    72. * @param file
    73. * @param response
    74. */
    75. public static void downloadZip(File file, HttpServletResponse response) {
    76. try {
    77. if (!file.exists()) {
    78. file.createNewFile();
    79. }
    80. // 以流的形式下载文件。
    81. BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
    82. byte[] buffer = new byte[fis.available()];
    83. fis.read(buffer);
    84. fis.close();
    85. // 清空response
    86. response.reset();
    87. OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
    88. response.setContentType("application/octet-stream");
    89. response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
    90. toClient.write(buffer);
    91. toClient.flush();
    92. toClient.close();
    93. file.delete(); //将生成的服务器端文件删除
    94. } catch (IOException ex) {
    95. ex.printStackTrace();
    96. }
    97. }
    98. /**
    99. * 获得bean,通过ApplicationContext获取
    100. *
    101. * @return
    102. */
    103. public static Object getBean(String className) {
    104. HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    105. ServletContext sc = request.getSession().getServletContext();
    106. ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
    107. Class c;
    108. try {
    109. c = Class.forName(className);
    110. return ac.getBean(c);
    111. } catch (ClassNotFoundException e) {
    112. // TODO Auto-generated catch block
    113. e.printStackTrace();
    114. }
    115. return null;
    116. }
    117. }

    以上就是fastdfs文件下载的全部方法