当前位置:   article > 正文

图片的展示与批量下载_file-save 下载多张图片

file-save 下载多张图片

        原有项目使用Vue框架和Element组件库,图片展示和下载功能可细分为:

1. 图片展示是将单个图片点击后,弹窗显示,用户选择保存则以服务端id命名保存至本地;

2.下载功能分为单个图片下载和批量下载

        原有管理系统中增加上述功能,需要新增JSZip和FileSaver两个JS库,开发步骤如下:

1. 准备工作

        安装JSZip和FileSaver

  1. npm install jszip --save
  2. npm install file-saver --save

        JSZip  库用于处理和生成 ZIP 文件。主要用到该库中两个方法:

  • file ()是 JSZip 对象的一个方法,用于向 ZIP 文件中添加文件。它接受两个参数:要添加到 ZIP 文件中的文件名和文件内容;
  • generateAsync()用于异步生成 ZIP 文件。它返回一个 Promise,该 Promise 在 ZIP 文件生成完成后被解析。方法使用示例;
  1. const zip = new JSZip();
  2. // 添加一个文件到 ZIP 中
  3. zip.file("hello.txt", "Hello world!");
  4. // 生成ZIP压缩文件的异步操作
  5. zip.generateAsync({ type: "blob" })
  6. .then((content) => {
  7. // Do something
  8. });

        FileSaver 则用于将数据保存为文件。主要使用saveAs()方法,接受两个参数:要保存的文件名和要保存的数据。使用方法如下:[data]为二进制数据,将被保存到新创建image.jpg的本地文件中

  1. const blob = new Blob( [data], {type : 'image/jpeg'} );
  2. FileSaver.saveAs( blob, 'image.jpg' );

2. 编码阶段

        在页面中引入上述库

  1. import JSZip from 'jszip'
  2. import FileSaver from 'file-saver'

2.1 实现单个图片的下载、展示和保存

        图片的展示和保存都需要提前获取图片,先完成单个图片请求。此处,需使用responseType: 'blob' ,因为图片是二进制数据,而不是文本数据。如果我们将responseType设置为'text',则浏览器会尝试将二进制数据解析为文本数据,这将导致数据损坏。通过将responseType设置为'blob',我们告诉浏览器将响应数据作为二进制对象处理,这样我们就可以正确地下载图片。

        图片的签名信息获取,需要通过另外的接口get到,后续处理。此外,请求涉及到了跨域问题,通过Nginx代理解决,属于后端内容不再赘述。

  1. // 单个图片下载
  2. getFile(item) {
  3. return new Promise((resolve, reject) => {
  4. this.axios({
  5. url: baseUrl + item.requestUrl,
  6. method: 'get',
  7. headers: {
  8. 'Authorization': item.authToken,
  9. 'Signature': item.reqSignature,
  10. 'ClientId': item.clientId
  11. },
  12. // 设置此选项,响应数据类型设置为blob(arraybuffer也OK);未设置时请求数据为乱码
  13. responseType: 'blob'
  14. }).then((response) => {
  15. resolve(response) // 将下载的文件返回
  16. }).catch((error) => {
  17. reject(error.toString())
  18. })
  19. })
  20. },

        请求方法完成后,点击页面按钮触发showImage展示图片,此方法中调用getFile()获取图片,并显示在el-dialog弹窗中。实现中需要注意getFile()方法响应的数据是Blob对象,需要将其转换为url,以便赋值给el-image的src属性

  1. showImage(item) {
  2. this.startLoading()
  3. getImageTokenById({ idFaultResource: parseInt(item.value) }).then((resp) => {
  4. console.log(JSON.stringify(resp))
  5. if (resp.code === '200') {
  6. const param = {
  7. // resourceKey: resp.result.resourceKey,
  8. requestUrl: resp.result.requestUrl,
  9. authToken: resp.result.authToken,
  10. reqSignature: resp.result.reqSignature,
  11. clientId: resp.result.clientId
  12. }
  13. this.getFile(param).then((response) => {
  14. this.endLoading()
  15. this.dialogVisible = true
  16. console.log(JSON.stringify(response))
  17. // urlCreator用于创建URL对象。在浏览器中,window.URL和window.webkitURL对象可能存在一个或两个
  18. const urlCreator = window.URL || window.webkitURL
  19. // createObjectURL方法将一个Blob或MediaStream对象转换为URL,以便赋值给el-image的src属性
  20. const imageUrl = urlCreator.createObjectURL(response.data)
  21. console.log('URL::::' + JSON.stringify(imageUrl))
  22. this.dialogImageUrl = imageUrl
  23. this.dialogImageName = resp.result.resourceKey
  24. this.imageBlob = [response.data]
  25. }).catch((error) => {
  26. this.$message({
  27. showClose: true,
  28. message: '获取图片失败,' + error,
  29. type: 'error'
  30. })
  31. this.endLoading()
  32. })
  33. }
  34. }).catch((error) => {
  35. this.$message({
  36. showClose: true,
  37. message: error,
  38. type: 'error'
  39. })
  40. this.endLoading()
  41. })
  42. },

注:getImageById()方法需要提前获取签名信息;

        图片展示弹窗十分简单,添加标题,图片关闭按钮和下载按钮即可

  1. <el-dialog
  2. title="图片预览"
  3. :visible.sync="dialogVisible"
  4. size="tiny"
  5. :before-close="handleClose"
  6. >
  7. <!-- 图片展示 -->
  8. <el-image :src="dialogImageUrl" alt="图片加载中……" style="width: 100%;height: 100%;" />
  9. <span slot="footer" class="dialog-footer">
  10. <el-button type="primary" @click="saveImage(imageBlob, dialogImageName)">下载图片</el-button>
  11. </span>
  12. </el-dialog>

        点击下载图片调用saveAs()方法保存图片,将图片文件按照imageName命名保存,并隐藏弹窗。

  1. saveImage(data, imageName) {
  2. const blob = new Blob(data, { type: 'image/jpeg' })
  3. FileSaver.saveAs(blob, imageName + '.jpg')
  4. this.dialogImageUrl = ''
  5. this.dialogVisible = false
  6. this.$message({
  7. showClose: true,
  8. message: '图片下载完成!',
  9. type: 'success'
  10. })
  11. },

2.2 图片批量下载并压缩

        批量下载只需要,将图片列表遍历逐个下载,待所有图片下载完成调用saveAs()方法保存并压缩生成文件夹。

  1. // 批量导出图片
  2. downloadFile() {
  3. const zip = new JSZip()
  4. const imagesPromises = []
  5. const cache = {}
  6. this.startLoading()
  7. getImagesTokenById ({ idTrustOrder: this.idTrustOrder }).then((resp) => {
  8. if (resp.code === '200') {
  9. const imageList = resp.result.downloadImageList
  10. if (imageList.length === 0) {
  11. this.$message({
  12. showClose: true,
  13. message: '当前无可下载的故障内容!',
  14. type: 'warning'
  15. })
  16. this.endLoading()
  17. return
  18. }
  19. imageList.map((item) => {
  20. const promise = this.getFile(item).then((resp) => {
  21. // 逐个下载图片
  22. console.log('获取的图片内容::' + item.resourceKey + '.jpg' + resp.data)
  23. // 创建文件用file()方法,文件夹用floder()方法
  24. zip.file(item.resourceKey + '.jpg', resp.data, { binary: true })
  25. cache[item.resourceKey] = resp.data
  26. })
  27. imagesPromises.push(promise)
  28. })
  29. // 生成zip文件
  30. Promise.all(imagesPromises)
  31. .then(() => {
  32. this.endLoading()
  33. zip.generateAsync({
  34. type: 'blob' // 文件格式
  35. }).then((content) => {
  36. // 生成二进制流
  37. FileSaver.saveAs(content, '图片.zip') // 利用file-saver保存文件,自定义文件名图片.zip
  38. this.$message({
  39. showClose: true,
  40. message: '文件下载完成!',
  41. type: 'success'
  42. })
  43. })
  44. })
  45. .catch((error) => {
  46. this.$message({
  47. showClose: true,
  48. message: '文件下载失败!' + error,
  49. type: 'error'
  50. })
  51. this.endLoading()
  52. })
  53. }
  54. }).catch((error) => {
  55. this.$message({
  56. showClose: true,
  57. message: error,
  58. type: 'error'
  59. })
  60. this.endLoading()
  61. })
  62. },

3. 测试于总结

        测试功能可用,开发中遇到的问题主要是跨域,二进制数据的处理,还有IT限制我的接口

参考文献:

1. JS实现根据URL批量下载文件并压缩成zip文件_javascript技巧_脚本之家

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

闽ICP备14008679号