当前位置:   article > 正文

基于Springboot+Bootstrap的文件管理全套解决方案(文件列表、上传、预览、下载、删除、打包下载等)_boot strap 文件列表

boot strap 文件列表

前言:

最近,事业群上层领导要求7天内完成ABS项目中保理系统的一期开发。需求评审会后,我发现各个功能模块都有大量的文件材料展示与上传,为了提高开发效率,我与组长商量,我先开发文件模块,为其他同事提供公共方法,减少重复工作。

使用的前端技术栈:Bootstrap、Bootstrap-table、layer.js、layui.js、jquery.media.js

一、设计思路:

我的想法是:文件的展示依托于表格形式,表格内展示文件的类型、名称、操作等信息,然后通过表格中或表头上的按钮完成上传、下载、预览等操作。其次,我又考虑的文件模块复用性与拓展性,我将文件类型信息存入数据字典中。这样做的好处有两点:一是、方便以后文件类型的拓展,即新增加一种文件,不需要改页面,只需要配置数据字典;二是、方便同事复用文件模块方法,即调用者,只需要传入类型后,就可以渲染相关数据。文件模块和数据字段模块图示如下:

                                                                           图1 - 文件管理模块图片

                                                                           图2 - 数据字典模块图片 

二、具体实现:

1.文件列表:

列表基于Bootstrap-table完成的文件展示,我在这块还做了一个优化:可以根据开发者传入的文件类型展示相应的文件,如果没有,也会展示该类,但是没有文件名称和操作。具体演示和代码如下:

演示:

                                                                           图3 - 文件列表演示图片 

页面代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <meta charset="utf-8">
  4. <head th:include="include :: header">
  5. </head>
  6. <body class="gray-bg">
  7. <div class="wrapper wrapper-content ">
  8. <div class="row">
  9. <div class="col-sm-12">
  10. <div class="ibox float-e-margins">
  11. <label class="col-sm-2 control-label">上传文件例子</label>
  12. <input type="hidden" id="fileIds" name="fileIds">
  13. <div class="ibox-content">
  14. <div class="columns pull-left">
  15. <button type="button" class="layui-btn" id="uploadFile">
  16. <i class="fa fa-cloud"></i>上传文件1
  17. </button>
  18. <button type="button" class="btn btn-primary"
  19. onclick="uploadFilePage('A','fileTable')">
  20. <i class="fa fa-primary" aria-hidden="true"></i>上传文件2
  21. </button>
  22. </div>
  23. <div class="columns pull-right">
  24. <button class="btn btn-success" onclick="downloadZip1('1','A','')">一键打包下载1</button>
  25. <button class="btn btn-success" onclick="downloadZip2()">一键打包下载2</button>
  26. </div>
  27. <table class="table table-bordered" id="fileTable"></table>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. <div th:include="include :: footer"></div>
  34. <script type="text/javascript" src="/js/appjs/common/file/file.js"></script>
  35. <link href="/css/layui.css" rel="stylesheet">
  36. <script src="/js/layui.js"></script>
  37. </body>
  38. </html>

JS代码:考虑到文件的复用性,初始化表格的JS入参有好几个 

  1. $(function () {
  2. initFileTable('1','A','','fileTable','1');
  3. });
  4. /**
  5. * 初始化文件表格
  6. *
  7. * @param belongId 所属ID (必传)
  8. * @param type 文件总类型 (必传)
  9. * @param fileTag 文件分类型
  10. * @param tableId 表格id (必传)
  11. * @param delFlag 删除表示 (必传)
  12. */
  13. function initFileTable(belongId,type,fileTag,tableId,delFlag) {
  14. $("#"+tableId).bootstrapTable({
  15. striped: true, // 设置为true会有隔行变色效果
  16. cache: false,
  17. sortable: false,
  18. url: filePrefix+"/listByBelongIdAndTypeAndFileTag",
  19. method: "get",
  20. dataType: "json", // 服务器返回的数据类型
  21. queryParams: {"belongId": belongId,"type":type,"fileTag":fileTag},
  22. onLoadSuccess: function(data) {
  23. },
  24. columns: [
  25. {
  26. checkbox: true
  27. },
  28. {
  29. class: 'uid',
  30. title: '序号',
  31. align: 'center',
  32. formatter: function (value, row, index) {
  33. return index + 1;
  34. }
  35. },
  36. {
  37. field: "id",
  38. visible: false
  39. },
  40. {
  41. field: "uuid",
  42. visible: false
  43. },
  44. {
  45. title: '上传文件',
  46. align: 'center',
  47. formatter: function (value, row, index) {
  48. return uploadFileBtn(row,tableId);
  49. }
  50. },
  51. {
  52. field: "typeName",
  53. align: 'center',
  54. title: "文件总类型",
  55. visible: false
  56. },
  57. {
  58. field: "fileTagName",
  59. align: 'center',
  60. title: "文件类型"
  61. },
  62. {
  63. field: "fileName",
  64. align: 'center',
  65. title: "文件名"
  66. },
  67. {
  68. title: '操作',
  69. align: 'center',
  70. formatter: function (value, row, index) {
  71. var id = row.id;
  72. if(id==null){
  73. return '-';
  74. }
  75. var p = '<a class="btn btn-warning btn-xs' + '" title="预览" mce_href="#" onclick="previewFile(\''
  76. + row.url
  77. + '\')">预览</a> ';
  78. var e = '<a class="btn btn-success btn-xs' + '" title="下载" mce_href="#" onclick="downloadFile(\''
  79. + id
  80. + '\')">下载</a> ';
  81. var d = '<a class="btn btn-danger btn-xs' + '" title="删除" mce_href="#" onclick="deleteFile(\''+ id+'\',\''+tableId+ '\')">删除</a> ';
  82. if(delFlag=='1'){
  83. return p + e + d;
  84. }else {
  85. return p + e;
  86. }
  87. }
  88. }
  89. ]
  90. })
  91. }

Java代码: 

  1. -----------------Controller------------------
  2. /**
  3. * 文件Demo
  4. *
  5. * @return
  6. */
  7. @GetMapping()
  8. private String File(){
  9. return "common/file/file";
  10. }
  11. /**
  12. * 查询文件列表
  13. *
  14. * @param belongId
  15. * @param type
  16. * @param fileTag
  17. * @return
  18. */
  19. @GetMapping("/listByBelongIdAndTypeAndFileTag")
  20. @ResponseBody
  21. public List<FileDTO> listByTypeAndFileTag(@RequestParam("belongId") Long belongId,
  22. @RequestParam("type") String type,
  23. @RequestParam("fileTag") String fileTag){
  24. List<FileDTO> busFileDOList=new ArrayList<>();
  25. try {
  26. busFileDOList =fileService.listByBelongIdAndTypeAndFileTag(belongId,type,fileTag);
  27. } catch (Exception e) {
  28. log.info("查询文件信息,异常信息:[{}]",e.getMessage());
  29. }
  30. return busFileDOList;
  31. }
  32. -----------------Service------------------
  33. @Override
  34. public List<FileDTO> listByBelongIdAndTypeAndFileTag(Long belongId, String type, String fileTag) {
  35. return fileDao.listByBelongIdAndTypeAndFileTag(belongId,type,fileTag);
  36. }

2.文件上传: 

文件上传,我这里提供了三种方式,第一种方式:我们原来项目中常用方法,它是使用了layui.js插件,这插件的作者帮助我们封装了好多前端方法和前端样式,方便我们调用;第二种方式:是我新想出来的一种方式,点击上传按钮,进入一个上传页面,在页面中有一个下拉框可以选择上传文件类型,还有一个上传按钮用来上传文件,然后点击提交;第三种方式:是原型上要求的方式,这次开发时间比较紧张,我在开发的中就没有研究和使用,它是把按钮放在了列表中,不同列代表上传不同的文件类型,用户体验感比较好。而且,我这里还做一个优化,如果上传的文件在列表中不存在文件,就在原位置插入,反之,则在这个类型文件的最后一行后边插入(因为要实现这个,我引入一个唯一标识UUID)。具体演示和代码如下:

方式一:

  • 演示:

点击上传按钮,上传文件就可以,缺点就是要在按钮的方法中固定上传的类型,单类型可以使用。

                                                                          图4 - 文件上传方式一演示图片  

  • 页面代码: 
<button type="button" class="layui-btn" id="uploadFile"><i class="fa fa-cloud"></i>上传文件1</button>
  • JS代码: 
  1. $(function () {
  2. fileUpload('A','A01','fileTable');
  3. });
  4. /**
  5. * 上传
  6. *
  7. * @param type
  8. * @param fileTag
  9. * @param tableId
  10. */
  11. function fileUpload(type,fileTag,tableId) {
  12. layui.use('upload', function () {
  13. var upload = layui.upload;
  14. //执行实例
  15. var uploadInst = upload.render({
  16. elem: '#uploadFile', //绑定元素
  17. url: filePrefix+'/uploadFile1/'+type+'/'+fileTag, //上传接口
  18. size: 102400,
  19. accept: 'file',
  20. done: function (data) {
  21. if (data.code == 0) {
  22. var busFile = data.busFile;
  23. //插入一条数据
  24. insertFile(busFile,tableId);
  25. }
  26. layer.msg(data.msg);
  27. },
  28. error: function (data) {
  29. layer.msg(data.msg);
  30. }
  31. });
  32. });
  33. }
  34. /**
  35. * 插入文件
  36. *
  37. * @param row
  38. * @param tableId
  39. */
  40. function insertFile(row,tableId) {
  41. var table = $("#"+tableId);
  42. var rows = table.bootstrapTable('getData');
  43. var type = row.type;
  44. var fileTag = row.fileTag;
  45. var uuid=null;
  46. var insertIndex = rows.length-1;
  47. //寻找插入文件文件位置和可能需要删除的行
  48. $.each(rows, function (i, oldRow) {
  49. if(type==oldRow.type && fileTag==oldRow.fileTag){
  50. if(null == oldRow.id){
  51. uuid=oldRow.uuid;
  52. insertIndex=i;
  53. }else {
  54. insertIndex=i+1;
  55. }
  56. }
  57. });
  58. // 删除表格空的数据
  59. if(uuid!=null){
  60. var values = [uuid];
  61. table.bootstrapTable('remove', {
  62. field: 'uuid',
  63. values: values
  64. });
  65. }
  66. // 表格插入一条
  67. table.bootstrapTable('insertRow', {
  68. index: insertIndex,
  69. row: row
  70. });
  71. }
  • Java代码:
  1. -----------------Controller------------------
  2. /**
  3. * 上传文件1
  4. *
  5. * @param file
  6. * @param type
  7. * @param fileTag
  8. * @return
  9. */
  10. @PostMapping("/uploadFile1/{type}/{fileTag}")
  11. @ResponseBody
  12. public R uploadFile1(@RequestParam("file") MultipartFile file, @PathVariable("type") String type, @PathVariable("fileTag") String fileTag) {
  13. log.info("上传文件开始,type:[{}],fileTag:[{}]",type,fileTag);
  14. if (file == null || StringUtil.isBlank(file.getOriginalFilename())) {
  15. log.info("未选择文件");
  16. return R.error("请选择需要上传的文件");
  17. }
  18. Map<String, Object> map = new HashMap<>(2);
  19. try {
  20. FileDTO busFile = fileService.uploadFile(file, type, fileTag);
  21. map.put("busFile", busFile);
  22. log.info("上传文件结束,type:[{}],fileTag:[{}],id:[{}],fileName:[{}]",type,fileTag,busFile.getId(),busFile.getFileFull());
  23. } catch (IOException e) {
  24. log.info("上传文件IO流异常:异常信息:[{}]",e.getMessage());
  25. return R.error("上传文件IO流异常:异常信息:"+e.getMessage());
  26. }catch (Exception e){
  27. log.info("上传文件异常:异常信息:[{}]",e.getMessage());
  28. return R.error("上传文件异常:异常信息:"+e.getMessage());
  29. }
  30. return R.ok(map);
  31. }
  32. -----------------Service------------------
  33. @Override
  34. public FileDTO uploadFile(MultipartFile file, String type, String fileTag) throws IOException {
  35. FileDTO busFile = new FileDTO();
  36. Date now = new Date();
  37. String fileName = file.getOriginalFilename();
  38. String preName = fileName.substring(0, fileName.lastIndexOf("."));
  39. String extName = fileName.substring(fileName.lastIndexOf(".") + 1);
  40. // 上传文件到Fast
  41. // StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
  42. // String groupPath = storePath.getFullPath();
  43. // String serverPath = fdfsConfig.getUrl();
  44. String serverPath = "https://img-blog.csdnimg.cn";
  45. String groupPath = "/20200404131040657.png";
  46. String fileUrl=null;
  47. // 处理fileUrl
  48. if (serverPath.endsWith("/")) {
  49. fileUrl = serverPath + groupPath;
  50. } else {
  51. fileUrl = serverPath + "/" + groupPath;
  52. }
  53. //封装数据
  54. busFile.setFileName(preName)
  55. .setFileExt(extName)
  56. .setFileFull(fileName)
  57. .setUrl(fileUrl)
  58. .setType(type)
  59. .setServerPath(serverPath)
  60. .setGroupPath(groupPath)
  61. .setFileTag(fileTag)
  62. .setCreateTime(now)
  63. .setUpdateTime(now)
  64. .setDelFlag(0);
  65. fileDao.save(busFile);
  66. //处理数据
  67. DictDO dict = dictDao.getByTypeAndValue(type, fileTag);
  68. busFile.setTypeName(dict.getDescription());
  69. busFile.setFileTagName(dict.getName());
  70. busFile.setUuid(UUID.randomUUID().toString());
  71. return busFile;
  72. }

方式二: 

  • 演示:

点击上传按钮,进入上传页面:选择类型、上传文件、点击提交。

                                                             图5-文件上传方式二演示图片  

                                                           图6 - 文件上传方式二演示图片  

  • 页面代码: 
  1. ---------------------------按钮----------------------
  2. <button type="button" class="btn btn-primary" onclick="uploadFilePage('A','fileTable')">
  3. <i class="fa fa-primary" aria-hidden="true"></i>上传文件2</button>
  4. ---------------------------上传页面----------------------
  5. <!DOCTYPE html>
  6. <html>
  7. <meta charset="utf-8">
  8. <head th:include="include :: header">
  9. </head>
  10. <body class="gray-bg">
  11. <div class="wrapper wrapper-content ">
  12. <div class="row">
  13. <div class="col-sm-12">
  14. <div class="ibox float-e-margins">
  15. <div class="ibox-content">
  16. <form class="form-horizontal m-t" id="signupForm" method="post" enctype="multipart/form-data">
  17. <input type="hidden" id="type" name="type" th:value="${type}"/>
  18. <input type="hidden" id="tableId" name="tableId" th:value="${tableId}"/>
  19. <div class="form-group">
  20. <label class="col-sm-2 control-label">文件类型:<i style="color: red;">*</i></label>
  21. <div class="col-sm-4">
  22. <select id="fileTag" name="fileTag" data-placeholder="请选择文件类型"
  23. class="col-sm-4 form-control chosen-select "
  24. tabindex="2" style="width: 100%"> <i style="color: red;">*</i>
  25. <option th:each="busDict:${busDictList}"
  26. th:value="${busDict.value}"
  27. th:text="${busDict.name}"></option>
  28. </select>
  29. </div>
  30. </div>
  31. <div class="form-group">
  32. <label class="col-sm-2 control-label">文件名称:</label>
  33. <div class="col-sm-3">
  34. <input id="fileupload" type="file" name="file" style="display:none;" />
  35. <input type='text' class="form-control" name='textfield' id='textfield' readonly="readonly"/>
  36. </div>
  37. <div class="col-sm-1">
  38. <input id="excelImport" type="button" value="上传" class="btn btn-success"/>
  39. </div>
  40. </div>
  41. <div class="form-group">
  42. <div class="col-sm-12 col-sm-offset-6">
  43. <button type="button" class="btn btn-primary" onclick="uploadFile()" >提交</button>
  44. </div>
  45. </div>
  46. </form>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </div>
  52. <div th:include="include :: footer"></div>
  53. <link href="/css/layui.css" rel="stylesheet">
  54. <script src="/js/layui.js"></script>
  55. <script type="text/javascript" src="/js/appjs/common/file/uploadFile.js"></script>
  56. </body>
  57. </html>
  • JS代码: 
  1. ---------------------------按钮JS----------------------
  2. /**
  3. * 上传文件页面
  4. *
  5. * @param type
  6. * @param tableId
  7. */
  8. function uploadFilePage(type,tableId) {
  9. var index = layer.open({
  10. type: 2,
  11. title: '上传文件',
  12. maxmin: true,
  13. shadeClose: false, // 点击遮罩关闭层
  14. area: ['800px', '520px'],
  15. content: filePrefix+'/uploadFilePage/' + type+'/'+tableId
  16. });
  17. layer.full(index);
  18. }
  19. ---------------------------页面JS----------------------
  20. var filePrefix = "/common/file";
  21. $(function () {
  22. });
  23. $("#excelImport").click(function() {
  24. $('#fileupload').click();
  25. });
  26. $('#fileupload').change(function(){
  27. $('#textfield').val( document.getElementById("fileupload").files[0].name);
  28. })
  29. function uploadFile() {
  30. var fileBtnId='signupForm';
  31. var type=$('#type').val();
  32. var fileTag= $('#fileTag option:selected').val();
  33. var tableId=$('#tableId').val();
  34. $.ajax({
  35. type: "POST",
  36. dataType: "json",
  37. cache: false,
  38. processData: false,
  39. contentType: false,
  40. url: filePrefix+"/uploadFile1/"+type+"/"+fileTag,
  41. data: new FormData($('#'+fileBtnId)[0]),
  42. success: function (data) {
  43. if (data.code == 0) {
  44. parent.layer.msg("操作成功");
  45. parent.insertFile(data.busFile,tableId);
  46. var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
  47. parent.layer.close(index);
  48. } else {
  49. parent.layer.alert(data.msg)
  50. }
  51. }
  52. });
  53. }
  •  Java代码:
  1. -----------------Controller------------------
  2. /**
  3. * 上传文件页面
  4. *
  5. * @param type
  6. * @param model
  7. * @return
  8. */
  9. @GetMapping("/uploadFilePage/{type}/{tableId}")
  10. public String uploadFilePage(@PathVariable("type") String type,@PathVariable("tableId") String tableId, Model model) {
  11. List<DictDO> busDictList = dictDao.listByType(type);
  12. model.addAttribute("type",type);
  13. model.addAttribute("tableId",tableId);
  14. model.addAttribute("busDictList",busDictList);
  15. return "common/file/uploadFile";
  16. }
  17. /**
  18. * 上传文件2
  19. *
  20. * @param file
  21. * @param type
  22. * @param fileTag
  23. * @return
  24. */
  25. @PostMapping("/uploadFile2")
  26. @ResponseBody
  27. public R uploadFile2(@RequestParam("file") MultipartFile file,@RequestParam("type") String type, @RequestParam("fileTag") String fileTag) {
  28. log.info("上传文件开始,type:[{}],fileTag:[{}]",type,fileTag);
  29. if (file == null || StringUtil.isBlank(file.getOriginalFilename())) {
  30. log.info("未选择文件");
  31. return R.error("请选择需要上传的文件");
  32. }
  33. Map<String, Object> map = new HashMap<>(2);
  34. try {
  35. FileDTO busFile = fileService.uploadFile(file, type, fileTag);
  36. map.put("busFile", busFile);
  37. log.info("上传文件结束,type:[{}],fileTag:[{}],id:[{}],fileName:[{}]",type,fileTag,busFile.getId(),busFile.getFileFull());
  38. } catch (IOException e) {
  39. log.info("上传文件IO流异常:异常信息:[{}]",e.getMessage());
  40. return R.error("上传文件IO流异常:异常信息:"+e.getMessage());
  41. }catch (Exception e){
  42. log.info("上传文件异常:异常信息:[{}]",e.getMessage());
  43. return R.error("上传文件异常:异常信息:"+e.getMessage());
  44. }
  45. return R.ok(map);
  46. }
  47. -----------------Service------------------
  48. 与方式一相同

 方式三: 

  • 演示:

点击上传按钮,就可以上传文件。

                                                                          图7 - 文件上传方式三演示图片  

  • 页面代码:

没有页面代码,页面是通过js渲染的。

  • JS代码: 
  1. /**
  2. * 上传文件按钮
  3. *
  4. * @param row
  5. * @param tableId
  6. * @returns {string}
  7. */
  8. function uploadFileBtn(row,tableId) {
  9. var formId=row.uuid;
  10. return '<button type="button" class="btn btn-primary" style="width: 82px;height: 25px;position: relative">'+
  11. '<form id="'+formId+'" method="post" enctype="multipart/form-data">' +
  12. '<input type="hidden" name="type" value="'+row.type+'"/>'+
  13. '<input type="hidden" name="fileTag" value="'+row.fileTag+'"/>'+
  14. '<input type="file" name="file" onchange="uploadFile(\''+formId+'\',\''+tableId+'\')" style="width: 100%;height: 25px;padding:0;position: absolute;font-size: 10px;left:0;top: 0;opacity: 0;z-index:2;filter:alpha(opacity=0);cursor: pointer;"/>'+
  15. '</form>'+
  16. '<span style="position: absolute;left: 10%;top: 3px;z-index: 1;" >上传文件3</span>'+
  17. '</button>';
  18. }
  19. /**
  20. * 上传文件按钮-上传方法
  21. *
  22. * @param formId
  23. * @param tableId
  24. */
  25. function uploadFile(formId,tableId) {
  26. $.ajax({
  27. type: "POST",
  28. dataType: "json",
  29. cache: false,
  30. processData: false,
  31. contentType: false,
  32. url: filePrefix+"/uploadFile2",
  33. data: new FormData($('#'+formId)[0]),
  34. success: function (data) {
  35. if (data.code == 0) {
  36. layer.msg("上传成功");
  37. insertFile(data.busFile,tableId);
  38. } else {
  39. layer.alert(data.msg)
  40. }
  41. }
  42. });
  43. }
  • Java代码:
  1. -----------------Controller------------------
  2. /**
  3. * 上传文件2
  4. *
  5. * @param file
  6. * @param type
  7. * @param fileTag
  8. * @return
  9. */
  10. @PostMapping("/uploadFile2")
  11. @ResponseBody
  12. public R uploadFile2(@RequestParam("file") MultipartFile file,@RequestParam("type") String type, @RequestParam("fileTag") String fileTag) {
  13. log.info("上传文件开始,type:[{}],fileTag:[{}]",type,fileTag);
  14. if (file == null || StringUtil.isBlank(file.getOriginalFilename())) {
  15. log.info("未选择文件");
  16. return R.error("请选择需要上传的文件");
  17. }
  18. Map<String, Object> map = new HashMap<>(2);
  19. try {
  20. FileDTO busFile = fileService.uploadFile(file, type, fileTag);
  21. map.put("busFile", busFile);
  22. log.info("上传文件结束,type:[{}],fileTag:[{}],id:[{}],fileName:[{}]",type,fileTag,busFile.getId(),busFile.getFileFull());
  23. } catch (IOException e) {
  24. log.info("上传文件IO流异常:异常信息:[{}]",e.getMessage());
  25. return R.error("上传文件IO流异常:异常信息:"+e.getMessage());
  26. }catch (Exception e){
  27. log.info("上传文件异常:异常信息:[{}]",e.getMessage());
  28. return R.error("上传文件异常:异常信息:"+e.getMessage());
  29. }
  30. return R.ok(map);
  31. }
  32. -----------------Service------------------
  33. 与方式一相同

3.文件预览: 

通过预览按钮进入预览页面,现在支持预览文件格式只有图片和PDF。具体演示和代码如下:

演示:

                                                                            图8 - 文件预览演示图片   

页面代码: 

  1. <!DOCTYPE html>
  2. <html>
  3. <meta charset="utf-8">
  4. <head th:include="include :: header">
  5. </head>
  6. <body class="gray-bg">
  7. <div class="wrapper wrapper-content ">
  8. <div class="row">
  9. <div class="col-sm-12">
  10. <div class="ibox float-e-margins">
  11. <div class="ibox-content" align="center">
  12. <a class="media" th:href="${url}"></a>
  13. </div>
  14. </div>
  15. </div>
  16. </div>
  17. </div>
  18. <div th:include="include :: footer"></div>
  19. <script type="text/javascript" src="/js/media/jquery.media.js"></script>
  20. <script type="text/javascript">
  21. $(function() {
  22. $('a.media').media({width:1200, height:600});
  23. $('a.mediase').media({width:1200, height:600});
  24. });
  25. </script>
  26. </body>
  27. </html>

JS代码:

  1. /**
  2. * 预览文件
  3. *
  4. * @param url
  5. */
  6. function previewFile(url) {
  7. //获取最后一个.的位置
  8. var index= url.lastIndexOf(".");
  9. //获取后缀
  10. var ext = url.substr(index+1);
  11. if(ext=='docx'||ext=='doc'||ext=='txt'||
  12. ext=='zip'||ext=='xlsx'||ext=='xls'||
  13. ext=='ppt'||ext=='pptx'){
  14. layer.msg("不支持此"+ext+"格式文件预览");
  15. return;
  16. }
  17. var index = layer.open({
  18. type: 2,
  19. title: '预览文件',
  20. maxmin: true,
  21. shadeClose: false, // 点击遮罩关闭层
  22. area: ['800px', '520px'],
  23. content: filePrefix+'/previewFile?url=' + url
  24. });
  25. layer.full(index);
  26. }

Java代码:

  1. /**
  2. * 预览文件
  3. *
  4. * @param url
  5. * @param model
  6. * @return
  7. */
  8. @GetMapping("/previewFile")
  9. public String previewFile(@RequestParam("url") String url, Model model) {
  10. model.addAttribute("url",url);
  11. return "common/file/previewFile";
  12. }

 4.文件下载: 

点击下载按钮,就可下载。具体代码如下:

页面代码: 

没有页面代码,JS渲染了一个按钮。

JS代码:

  1. /**
  2. * 下载文件
  3. *
  4. * @param id
  5. */
  6. function downloadFile(id) {
  7. window.location.href = filePrefix+"/downloadFile/" + id;
  8. }

Java代码:

  1. /**
  2. * 下载
  3. *
  4. * @param id
  5. * @return
  6. * @throws Exception
  7. */
  8. @GetMapping("/downloadFile/{id}")
  9. public ResponseEntity<byte[]> downloadFile(@PathVariable("id") Long id){
  10. FileDO file = fileDao.get(id);
  11. log.info("下载文件开始,文件id:[{}],文件名称:[{}]",file.getId(),file.getFileFull());
  12. byte[] content = ZipDownloadUtil.downloadUrlConvertByte(file.getUrl());
  13. HttpHeaders headers = new HttpHeaders();
  14. try {
  15. headers.set("Content-Disposition", "attachment;Filename=" + URLEncoder.encode(file.getFileFull(), "UTF-8"));
  16. } catch (UnsupportedEncodingException e) {
  17. log.info("文件名编码集转换异常,异常信息[{}]",e.getMessage());
  18. }
  19. HttpStatus statusCode = HttpStatus.OK;
  20. ResponseEntity<byte[]> entity = new ResponseEntity<>(content, headers, statusCode);
  21. return entity;
  22. }

5.文件删除:  

点击删除按钮,弹出删除却框,点击确定后删除,我这里是逻辑删除,只更新数据删除标识,不删除数据库记录和文件服务器中的文件。具体演示和代码如下:

演示:

                                                                            图9 - 文件删除演示图片    

页面代码: 

没有页面代码,JS渲染了一个按钮。

JS代码:

  1. /**
  2. * 删除文件
  3. *
  4. * @param id
  5. * @param tableId
  6. */
  7. function deleteFile(id,tableId) {
  8. layer.confirm("确认要删除此文件吗?",
  9. {btn: ['确定', '取消']}, function () {
  10. $.ajax({
  11. cache: true,
  12. type: "get",
  13. url: filePrefix+"/deleteFile/" + id,
  14. async: false,
  15. error: function (request) {
  16. parent.layer.alert("Connection error");
  17. },
  18. success: function (data) {
  19. if (data.code == 0) {
  20. var table = $("#"+tableId);
  21. var values = [parseInt(id)];
  22. table.bootstrapTable('remove', {
  23. field: 'id',
  24. values: values
  25. });
  26. layer.closeAll('dialog');
  27. parent.layer.msg("文件删除成功");
  28. } else {
  29. parent.layer.alert(data.msg)
  30. }
  31. }
  32. });
  33. })
  34. }

Java代码:

  1. /**
  2. * 删除文件
  3. *
  4. * @param id
  5. * @return
  6. */
  7. @ResponseBody
  8. @GetMapping("/deleteFile/{id}")
  9. public R deleteFile(@PathVariable("id") Long id) {
  10. try {
  11. fileDao.updateDelFlagById(id);
  12. } catch (Exception e) {
  13. log.info("删除文件信息,异常信息:[{}]",e.getMessage());
  14. return R.error("异常信息:"+e.getMessage());
  15. }
  16. return R.ok();
  17. }

6.文件打包下载:  

我这里提供了两种打包下载方法方式,第一种方式:根据文件类型和所属ID打成一个压缩包,第二种方式:根据所属id的集合批量下载,并且压缩包中会按照所属ID和文件类型创建不同目录下载(这块搞了好久,我对Java IO流不是很熟悉;JDK8 Stream 分组的功能帮了我很大忙,JDK8 Stream的使用,见我写的这篇文章《JDK8都发行5年多了,你还不会使用Stream流和Lambda表达式吗?》)。

方式一:

点击一键打包下载按钮,就可以下文件,这种方式需要传入文件类型和所属ID,具体代码如下。

  • 页面代码:
<button class="btn btn-success" onclick="downloadZip1('1','A','')">一键打包下载1</button>
  • JS代码: 
  1. /**
  2. * 打包下载1
  3. *
  4. * @param belongId
  5. * @param type
  6. * @param fileTag
  7. */
  8. function downloadZip1(belongId,type,fileTag) {
  9. window.location.href = filePrefix+"/downloadZip1?belongId=" + belongId+"&type="+type+"&fileTag"+fileTag;
  10. }
  • Java代码:
  1. -----------------Controller------------------
  2. /**
  3. * 打包下载1
  4. *
  5. * @param belongId
  6. * @param type
  7. * @param fileTag
  8. */
  9. @GetMapping("/downloadZip1")
  10. @ResponseBody
  11. public void downloadZip1(@RequestParam("belongId") Long belongId,
  12. @RequestParam("type") String type,
  13. @RequestParam("fileTag") String fileTag,
  14. HttpServletResponse response) {
  15. log.info("打包下载文件开始,文件所属id:[{}],文件总类型:[{}],文件类型:[{}]",belongId,type,fileTag);
  16. try {
  17. fileService.downloadZip(belongId,type,fileTag,"压缩包",response);
  18. log.info("打包下载文件结束,文件所属id:[{}],文件总类型:[{}],文件类型:[{}]",belongId,type,fileTag);
  19. } catch (Exception e) {
  20. log.error("打包下载文件异常,异常信息:[{}]", e.getMessage());
  21. }
  22. }
  23. -----------------Service------------------
  24. @Override
  25. public void downloadZip(Long belongId, String type, String fileTag, String zipFilename, HttpServletResponse response) throws IOException {
  26. Map<String, Object> map = new HashMap<>(4);
  27. map.put("belongId", belongId);
  28. map.put("type", type);
  29. map.put("fileTag", fileTag);
  30. List<FileDTO> list = fileDao.list(map);
  31. List<byte[]> contentList = new ArrayList<>();
  32. List<String> filenameList = new ArrayList<>();
  33. String typeName = "";
  34. if (!list.isEmpty()) {
  35. typeName = list.get(0).getTypeName();
  36. list.forEach(x -> {
  37. log.info("文件名称和url,name:[{}],url:[{}] ", x.getFileName(), x.getUrl());
  38. if (StringUtil.isNotBlank(x.getUrl())) {
  39. contentList.add(ZipDownloadUtil.downloadUrlConvertByte(x.getUrl()));
  40. filenameList.add(getFilename(x));
  41. }
  42. });
  43. }
  44. ZipDownloadUtil.downloadZip(response, zipFilename, contentList, filenameList);
  45. }

方式二:

点击一键打包下载按钮,就可以下文件,这种方式需要所属ID类型和压缩包名称,具体代码如下。

  • 页面代码:
<button class="btn btn-success" onclick="downloadZip2()">一键打包下载2</button>
  • JS代码: 
  1. /**
  2. * 打包下载2
  3. */
  4. function downloadZip2() {
  5. var params={};
  6. params.belongIds=[1,2];
  7. params.zipFilename='测试';
  8. var param = jQuery.param(params);
  9. window.location.href = filePrefix+"/downloadZip2?" + param;
  10. }
  • Java代码:
  1. -----------------Controller------------------
  2. /**
  3. *
  4. * 打包下载2
  5. *
  6. * @param belongIds
  7. * @param zipFilename
  8. */
  9. @GetMapping("/downloadZip2")
  10. @ResponseBody
  11. public void downloadZip2(@RequestParam("belongIds[]") List<Long> belongIds,
  12. @RequestParam("zipFilename") String zipFilename,
  13. HttpServletResponse response) {
  14. log.info("打包下载文件开始,文件所属id集合:[{}]", JsonUtil.beanToJson(belongIds));
  15. try {
  16. fileService.batchDownloadZip(belongIds,zipFilename,response);
  17. log.info("打包下载文件结束,文件所属id集合:[{}],压缩文件名称:[{}]", JsonUtil.beanToJson(belongIds),zipFilename);
  18. } catch (Exception e) {
  19. log.error("打包下载文件异常,异常信息:[{}]", e.getMessage());
  20. }
  21. }
  22. -----------------Service------------------
  23. @Override
  24. public void batchDownloadZip(List<Long> belongIdList, String zipFilename, HttpServletResponse response) throws IOException {
  25. //数据为空
  26. if (belongIdList.isEmpty()) {
  27. return;
  28. }
  29. List<byte[]> contentList = new ArrayList<>();
  30. List<String> filenameList = new ArrayList<>();
  31. //遍历每一个资产包
  32. belongIdList.forEach(belongId->{
  33. Map<String,Object> param = new HashMap<>(2);
  34. param.put("belongId", belongIdList.get(0));
  35. List<FileDTO> list = fileDao.list(param);
  36. //按文件类型分组
  37. Map<String, List<FileDTO>> map = list.stream().collect(Collectors.groupingBy(FileDTO::getTypeName));
  38. String partlPackageNo = "";
  39. //遍历分组
  40. map.forEach((key, value)->{
  41. String typeName=key;
  42. value.forEach(x->{
  43. log.info("文件名称和url,name:[{}],url:[{}] ", x.getUrl(), x.getFileName());
  44. contentList.add(ZipDownloadUtil.downloadUrlConvertByte(x.getUrl()));
  45. filenameList.add(partlPackageNo+"/"+typeName+"/"+getFilename(x));
  46. });
  47. });
  48. });
  49. //封装压缩包名字
  50. zipFilename=zipFilename+"_"+ LocalDateTime.now().toString()+".zip";
  51. ZipDownloadUtil.downloadZip(response, zipFilename, contentList, filenameList);
  52. }

三、源码地址:

springboot_demo: springboot_demo 《 springboot-some-function模块》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/686230
推荐阅读
相关标签
  

闽ICP备14008679号