欢迎来到飞鸟慕鱼博客,开始您的技术之旅!
当前位置: 首页知识笔记正文

springbootvue文件管理列表,springbootvue文件列表操作

终极管理员 知识笔记 124阅读
场景

SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览)

SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览)_霸道流氓气质的博客-博客_vue openoffice

上面在使用OpenOffice实现doc、excel、ppt等文档的管理和预览。

除此之外可用kkFileView实现包括且更多文档的预览。

kkFileView

kkFileView - 在线文件预览

kkFileView为文件文档在线预览解决方案该项目使用流行的spring boot搭建易上手和部署

基本支持主流办公文档的在线预览如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等。

gitee地址

kkFileView: 使用spring boot打造文件文档在线预览项目解决方案支持doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3以及众多类文本如txt、html、xml、java、properties、sql、js、md、json、conf、ini、vue、php、py、bat、gitignore等文件在线预览

kkFileView部署和SpringBoot接入指南

具体参考文档

文档预览 - Gitee.com

这里是windows电脑所以直接下载发行版本并解压运行即可

kkFileView 发行版 - Gitee.com

 

解压之后找到bin下bat双击启动即可

 

启动成功之后访问:

出现如下界面则成功

 

 

项目接入使用

当您的项目内需要预览文件时只需要调用浏览器打开本项目的预览接口并传入须要预览文件的url

                    var url   //要预览文件的访问地址                    window.open( 

博客
霸道流氓气质的博客_博客-C#,架构之路,SpringBoot领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现 建表与后台SpringBoot代码生成

若依前后端分离版本地搭建开发环境并运行项目的教程

若依前后端分离版手把手教你本地搭建环境并运行项目_霸道流氓气质的博客-博客_运行若依分离版

基于上面搭建起来架构的基础上。

设计数据库表

DROP TABLE IF EXISTS bus_file_preview;CREATE TABLE bus_file_preview  (  id bigint(0) NOT NULL AUTO_INCREMENT COMMENT 主键,  file_name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 文件名,  preview_server_url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 预览服务地址,  file_path varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 文件磁盘路径,  file_url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 文件url,  create_time datetime(0) NULL DEFAULT NULL COMMENT 创建时间,  create_by varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 创建人,  update_time datetime(0) NULL DEFAULT NULL COMMENT 更新时间,  update_by varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 更新人,  remark varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 备注,  PRIMARY KEY (id) USING BTREE) ENGINE  InnoDB AUTO_INCREMENT  15 CHARACTER SET  utf8 COLLATE  utf8_general_ci COMMENT  文件上传与预览 ROW_FORMAT  Dynamic;SET FOREIGN_KEY_CHECKS  1;

表结构

 

使用若依自带代码生成工具生成代码下面展示部分代码

实体类BusFilePreview

import org.apache.commons.lang3.builder.ToStringBuilder;import org.apache.commons.lang3.builder.ToStringStyle;import com.ruoyi.common.annotation.Excel;import com.ruoyi.common.core.domain.BaseEntity;public class BusFilePreview extends BaseEntity{    private static final long serialVersionUID  1L;    /** 主键 */    private Long id;    /** 文件名 */    Excel(name  文件名)    private String fileName;    /** 预览服务地址 */    Excel(name  预览服务地址)    private String previewServerUrl;    /** 文件url */    Excel(name  文件url)    private String fileUrl;    /** 文件磁盘路径 */    Excel(name  文件磁盘路径)    private String filePath;    public void setId(Long id)    {        this.id  id;    }    public Long getId()    {        return id;    }    public void setFileName(String fileName)    {        this.fileName  fileName;    }    public String getFileName()    {        return fileName;    }    public void setPreviewServerUrl(String previewServerUrl)    {        this.previewServerUrl  previewServerUrl;    }    public String getPreviewServerUrl()    {        return previewServerUrl;    }    public void setFileUrl(String fileUrl)    {        this.fileUrl  fileUrl;    }    public String getFileUrl()    {        return fileUrl;    }    public void setFilePath(String filePath)    {        this.filePath  filePath;    }    public String getFilePath()    {        return filePath;    }    Override    public String toString() {        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)            .append(id, getId())            .append(fileName, getFileName())            .append(previewServerUrl, getPreviewServerUrl())            .append(fileUrl, getFileUrl())            .append(createTime, getCreateTime())            .append(createBy, getCreateBy())            .append(updateTime, getUpdateTime())            .append(updateBy, getUpdateBy())            .append(remark, getRemark())            .toString();    }}
文件上传功能实现

前端添加el-upload

    <!-- 添加或修改preview对话框 -->    <el-dialog :titletitle :visible.syncopen width35% append-to-body>      <el-form refform :modelform :rulesrules label-width110px>        <el-form-item label文件名 propfileName>          <el-input            v-modelform.fileName            placeholder请输入文件名            disabled          />        </el-form-item>        <el-form-item label附件 propphotoPath>          <el-upload            :headersheaders            :actionurl            :multiplefalse            :file-listfileList            :on-removefileRemove            :on-successuploadSuccess            :on-erroruploadError            :on-progressuploadProgress            :before-uploadbeforeUpload            :limit1            :on-exceedbeyond          >            <el-button sizesmall>              上传              <i classel-icon-upload el-icon--right></i>            </el-button>            <div classel-upload__tip stylecolor: red slottip>              提示仅允许导入.doc, .docx, .xls, .xlsx, .ppt, .pptx,              .pdf, .mp3,.mp4,.wav格式文件            </div>          </el-upload>        </el-form-item>      </el-form>      <div slotfooter classdialog-footer>        <el-button typeprimary clicksubmitForm>确 定</el-button>        <el-button clickcancel>取 消</el-button>      </div>    </el-dialog>

并设置各回调事件事件实现

    // 文件上传失败    uploadError(err) {      this.btnLoding  false;      this.$message.error(res.msg);    },    // 上传中    uploadProgress(e) {      this.btnLoding  true;    },    // 文件上传之前    beforeUpload(file) {      const fileName  file.name;      const fileType  fileName.substring(fileName.lastIndexOf(.));      const whiteList  [        .doc,        .docx,        .xls,        .xlsx,        .ppt,        .pptx,        .pdf,        .mp3,        .mp4,        .wav,      ];      //array.indexOf此方法判断数组中是否存在某个值如果存在返回数组元素的下标否则返回-1。      if (whiteList.indexOf(fileType)  -1) {        this.$message.error(只允许如下文件类型:  whiteList.toString());        return false;        // 不处理      } else {        this.form.fileName  file.name;      }    },    // 文件上传成功    uploadSuccess(res, file, fileList) {      this.form.previewServerUrl  res.previewServerUrl;      this.form.fileUrl  res.fileUrl;      this.form.filePath  res.filePath;      this.btnLoding  false;      this.fileList  fileList;      this.$message(res.msg);    },    beyond(file, fileList) {      this.$message({        message: 最多上传一个文件,        type: warning,      });    },    // 移除选择的文件    fileRemove(file, fileList) {      this.btnLoding  false;      this.reset();      this.fileList  [];    },

重点关注文件上传之前的beforeUpload和文件上传成功的uploadSuccess

上传之前获取文件名和后缀名然后判断是否为允许的文件类型如果允许获取文件名。

文件上传成功之后获取后台接口返回的文件预览服务地址和文件预览url以及磁盘路径三个参数。

其中文件预览服务地址指的是kkFileView的ip和端口号以及预览的url,比如这里是与后台服务放在了一起

所以previewServerUrl为

文件预览url为调用kkFileView预览时传递的参数比如

文件磁盘路径映射为网络url可以参考

SpringBoot中通过重写WebMvcConfigurer的方法配置静态资源映射实现图片上传后返回网络Url

SpringBoot中通过重写WebMvcConfigurer的方法配置静态资源映射实现图片上传后返回网络Url_霸道流氓气质的博客-博客

这里后台将预览文件的网络url单独返回是因为在前端进行预览时需要对url参数进行base64编码

如果不进行编码预览会有问题会提示

Illegal base64 character 3a

这点官网有说明

 

SpringBoot上传接口实现

代码实现

​    PostMapping(/uploadPreviewFile)    public AjaxResult uploadPreviewFile(Param(file) MultipartFile file) {        AjaxResult ajaxResult  AjaxResult.success();        try {            //D:/ruoyi/uploadPath/upload/2022/12/10/            String path  RuoYiConfig.getUploadPath()  /  DateUtils.datePath()  /;            FileUtils.check_folder(path);            // 上传后的文件名称            //423208ab-2171-4631-9e08-382c00aacc43.doc            String auth_file_name  UploadUtil.save_file_withAllow(file, path ,allowFiles);            if (StringUtils.isEmpty(auth_file_name)){                return AjaxResult.error(HttpStatus.BAD_REQUEST, 文件格式不合法);            }            ajaxResult.put(code, 200);            ajaxResult.put(message, 成功);            ajaxResult.put(fileName, auth_file_name);            ajaxResult.put(filePath, path  auth_file_name);            //serverConfig.getUrl()                 //Constants.RESOURCE_PREFIX     /profile            //RuoYiConfig.getUploadPathPre()  /upload            //File.separator       /            //DateUtils.datePath()   /2022/12/10            //auth_file_name    a28ffa19-9982-42d2-8766-1feb274c5bb7.doc            //url             String fileUrl  serverConfig.getUrl() Constants.RESOURCE_PREFIX  RuoYiConfig.getUploadPathPre()  File.separator  DateUtils.datePath()  File.separator  auth_file_name;            String previewServerUrl  Constants.HTTP  previewConfig.getServerIp() : previewConfig.getServerPort()  Constants.PREVIEW_SERVER_URL;            ajaxResult.put(previewServerUrl, previewServerUrl);            ajaxResult.put(fileUrl, fileUrl);        } catch (IOException e) {            ajaxResult.put(code, 400);            ajaxResult.put(message, 上传失败);            e.printStackTrace();        }        return ajaxResult;    }​

为方便更清晰的调试理解这里在生成网络url时标注了每一步的参数

首先调用若依的工具类获取并检查文件上传目录这里的RuoYiConfig.getUploadPath()配置的是D:/ruoyi/uploadPath

 

然后最终path的值为D:/ruoyi/uploadPath/upload/2022/12/10/

然后调用文件上传方法这里新建了一个重载方法传递了允许上传的文件类型若依自带的方法该参数是写死的

 public static String save_file_withAllow(MultipartFile file, String path ,String[] allowFiles) throws IOException {  String filenamefile.getOriginalFilename();  //后缀名校验  String suffix  filename.substring(filename.indexOf(.));  List<String> allowFileList  new ArrayList<>(Arrays.asList(allowFiles));  if (!allowFileList.contains(suffix)){   return null;  }  filename  UUID.randomUUID().toString()  suffix;  File file_tempnew File(path,filename);  if (!file_temp.getParentFile().exists()) {   file_temp.getParentFile().mkdir();  }  if (file_temp.exists()) {   file_temp.delete();  }  file_temp.createNewFile();  file.transferTo(file_temp);  return file_temp.getName(); }

允许上传的格式需要声明

    /**允许上传的格式*/    private static String[] allowFiles  {.doc, .docx, .xls, .xlsx, .ppt, .pptx, .pdf,.mp3,.mp4,.wav    };

上传成功之后获取到文件的文件名比如423208ab-2171-4631-9e08-382c00aacc43.doc

然后生成文件预览网络url

​            //serverConfig.getUrl()                 //Constants.RESOURCE_PREFIX     /profile            //RuoYiConfig.getUploadPathPre()  /upload            //File.separator       /            //DateUtils.datePath()   /2022/12/10            //auth_file_name    a28ffa19-9982-42d2-8766-1feb274c5bb7.doc            //url             String fileUrl  serverConfig.getUrl() Constants.RESOURCE_PREFIX  RuoYiConfig.getUploadPathPre()  File.separator  DateUtils.datePath()  File.separator  auth_file_name;​

这里的serverConfig是若依自带获取服务相关配置其它的就是一些常量配置。

RuoYiConfig.getUploadPathPre() 是自己新增的获取上传路径的前缀

    /**     * 获取上传路径前缀     */    public static String getUploadPathPre()    {        return /upload;    }

最后返回kkFileView服务预览的ip和端口以及前缀

String previewServerUrl  Constants.HTTP  previewConfig.getServerIp() : previewConfig.getServerPort()  Constants.PREVIEW_SERVER_URL;

这里将ip和端口写在配置文件中

#文件预览相关配置preview:  serverIp: 127.0.0.1  serverPort: 8012

 

然后新增配置文件获取

import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;ComponentConfigurationProperties(prefix  preview)public class PreviewConfig {    private String serverIp;    private String serverPort;    public String getServerIp() {        return serverIp;    }    public void setServerIp(String serverIp) {        this.serverIp  serverIp;    }    public String getServerPort() {        return serverPort;    }    public void setServerPort(String serverPort) {        this.serverPort  serverPort;    }}

最终返回的previewServerUrl为

 

上传成功之后前端获取返回参数并赋值到form中前端点击提交按钮时

    /** 提交按钮 */    submitForm() {      this.$refs[form].validate((valid) > {        if (valid) {          if (this.form.id ! null) {            updatePreview(this.form).then((response) > {              this.msgSuccess(修改成功);              this.open  false;              this.fileList  [];              this.getList();            });          } else {            addPreview(this.form).then((response) > {              this.msgSuccess(新增成功);              this.open  false;              this.fileList  [];              this.getList();            });          }        }      });    },

将数据存储到数据库中。

文件上传效果实现

 

文件下载实现

前端下载按钮点击事件

    // 下载    handleDownload(row) {      var filePath  row.filePath;      var fileName  row.fileName;      var url         this.downloadUrl  ?filePath  filePath  &fileName  fileName;      const a  document.createElement(a);      a.setAttribute(download, fileName);      a.setAttribute(target, _blank);      a.setAttribute(href, url);      a.click();    },

获取文件磁盘路径和文件名并传递参数

后台SpringBoot接口

    GetMapping(download)    ApiOperation(下载)    public void downloadFile(String filePath,String fileName, HttpServletResponse response) throws IOException {        File file  new File(filePath);        // 清空response        response.reset();        // 设置response的Header 通知浏览器 已下载的方式打开文件 防止文本图片预览        response.addHeader(Content-Disposition,                attachment;filename  new String(fileName.getBytes(gbk), iso-8859-1)); // 转码之后下载的文件不会出现中文乱码        response.addHeader(Content-Length,   file.length());        // 以流的形式下载文件        InputStream fis  new BufferedInputStream(new FileInputStream(filePath));        byte[] buffer  new byte[fis.available()];        fis.read(buffer);        fis.close();        OutputStream toClient  new BufferedOutputStream(response.getOutputStream());        toClient.write(buffer);        toClient.flush();        toClient.close();    }

文件下载效果

 

预览实现

前端点击预览的点击事件

    // 预览    handlePreview(row) {      var previewServerUrl  row.previewServerUrl;      var fileUrl  row.fileUrl;      //分别获取预览服务地址和预览参数的地址然后拼接      //预览文件url地址需要使用Base64编码URL      let url         previewServerUrl  encodeURIComponent(Base64.encodeURI(fileUrl));      window.open(url);    },

注意这里获取预览服务地址和预览参数文件url,这里需要将文件url进行Base64编码

Vue中使用Base64编码

安装依赖

npm install --save js-base64

引入依赖

import { Base64 } from js-base64;

调用编码方法

Base64.encodeURI(fileUrl)
预览效果

代码完整示例

前端Vue页面完整示例代码

<template>  <div classapp-container>    <el-form      :modelqueryParams      refqueryForm      :inlinetrue      v-showshowSearch      label-width68px    >      <el-form-item label文件名 propfileName>        <el-input          v-modelqueryParams.fileName          placeholder请输入文件名          clearable          sizesmall          keyup.enter.nativehandleQuery        />      </el-form-item>       <el-form-item>        <el-button          typecyan          iconel-icon-search          sizemini          clickhandleQuery          >搜索</el-button        >        <el-button iconel-icon-refresh sizemini clickresetQuery          >重置</el-button        >      </el-form-item>    </el-form>    <el-row :gutter10 classmb8>      <el-col :span1.5>        <el-button          typeprimary          iconel-icon-plus          sizemini          clickhandleAdd          v-hasPermi[basicinfomanage:preview:add]          >新增</el-button        >      </el-col>      <el-col :span1.5>        <el-button          typesuccess          iconel-icon-edit          sizemini          :disabledsingle          clickhandleUpdate          v-hasPermi[basicinfomanage:preview:edit]          >修改</el-button        >      </el-col>      <el-col :span1.5>        <el-button          typedanger          iconel-icon-delete          sizemini          :disabledmultiple          clickhandleDelete          v-hasPermi[basicinfomanage:preview:remove]          >删除</el-button        >      </el-col>      <right-toolbar        :showSearch.syncshowSearch        queryTablegetList      ></right-toolbar>    </el-row>    <el-table      v-loadingloading      :datapreviewList      selection-changehandleSelectionChange    >      <el-table-column typeselection width55 aligncenter />      <el-table-column        show-overflow-tooltip        label文件名        aligncenter        propfileName      />      <el-table-column        label操作        aligncenter        class-namesmall-padding fixed-width        width200      >        <template slot-scopescope>          <el-button            sizemini            typetext            iconel-icon-edit            clickhandleUpdate(scope.row)            v-hasPermi[basicinfomanage:preview:edit]            >修改</el-button          >          <el-button            sizemini            typetext            iconel-icon-edit            clickhandlePreview(scope.row)            >预览</el-button          >          <el-button            sizemini            typetext            iconel-icon-edit            clickhandleDownload(scope.row)            >下载</el-button          >          <el-button            sizemini            typetext            iconel-icon-delete            clickhandleDelete(scope.row)            v-hasPermi[basicinfomanage:preview:remove]            >删除</el-button          >        </template>      </el-table-column>    </el-table>    <pagination      v-showtotal > 0      :totaltotal      :page.syncqueryParams.pageNum      :limit.syncqueryParams.pageSize      paginationgetList    />    <!-- 添加或修改preview对话框 -->    <el-dialog :titletitle :visible.syncopen width35% append-to-body>      <el-form refform :modelform :rulesrules label-width110px>        <el-form-item label文件名 propfileName>          <el-input            v-modelform.fileName            placeholder请输入文件名            disabled          />        </el-form-item>        <el-form-item label附件 propphotoPath>          <el-upload            :headersheaders            :actionurl            :multiplefalse            :file-listfileList            :on-removefileRemove            :on-successuploadSuccess            :on-erroruploadError            :on-progressuploadProgress            :before-uploadbeforeUpload            :limit1            :on-exceedbeyond          >            <el-button sizesmall>              上传              <i classel-icon-upload el-icon--right></i>            </el-button>            <div classel-upload__tip stylecolor: red slottip>              提示仅允许导入.doc, .docx, .xls, .xlsx, .ppt, .pptx,              .pdf, .mp3,.mp4,.wav格式文件            </div>          </el-upload>        </el-form-item>      </el-form>      <div slotfooter classdialog-footer>        <el-button typeprimary clicksubmitForm>确 定</el-button>        <el-button clickcancel>取 消</el-button>      </div>    </el-dialog>  </div></template><script>import {  listPreview,  getPreview,  delPreview,  addPreview,  updatePreview,} from /api/basicinfomanage/preview;import { getToken } from /utils/auth;import { Base64 } from js-base64;export default {  name: Preview,  data() {    return {      // 遮罩层      loading: true,      // 选中数组      ids: [],      // 非单个禁用      single: true,      // 非多个禁用      multiple: true,      // 显示搜索条件      showSearch: true,      // 总条数      total: 0,      // preview表格数据      previewList: [],      // 弹出层标题      title: ,      // 是否显示弹出层      open: false,      // 查询参数      queryParams: {        pageNum: 1,        pageSize: 10,        fileName: null,      },      // 表单参数      form: {},      // 表单校验      rules: {        fileName: [          {            required: true,            message: 文件名称不能为空,            trigger: blur,          },        ],      },      // 上传按钮闸口      btnLoding: false,      //  请求头      headers: { Authorization: Bearer     getToken() },      // 上传地址      url:        process.env.VUE_APP_BASE_API         /fzys/basicinfomanage/preview/uploadPreviewFile,      // 下载地址      downloadUrl:        process.env.VUE_APP_BASE_API  /fzys/basicinfomanage/preview/download,      // 图片列表      fileList: [],    };  },  created() {    this.getList();  },  methods: {    /** 查询preview列表 */    getList() {      this.loading  true;      listPreview(this.queryParams).then((response) > {        this.previewList  response.rows;        this.total  response.total;        this.loading  false;      });    },    // 取消按钮    cancel() {      this.open  false;      this.reset();    },    // 表单重置    reset() {      this.form  {        id: null,        fileName: null,      };      this.resetForm(form);    },    /** 搜索按钮操作 */    handleQuery() {      this.queryParams.pageNum  1;      this.getList();    },    /** 重置按钮操作 */    resetQuery() {      this.resetForm(queryForm);      this.handleQuery();    },    // 多选框选中数据    handleSelectionChange(selection) {      this.ids  selection.map((item) > item.id);      this.single  selection.length ! 1;      this.multiple  !selection.length;    },    /** 新增按钮操作 */    handleAdd() {      this.fileRemove();      this.open  true;      this.title  添加文件;    },    /** 修改按钮操作 */    handleUpdate(row) {      this.reset();      const id  row.id || this.ids;      getPreview(id).then((response) > {        this.form  response.data;        this.open  true;        this.title  修改文件;      });    },    // 预览    handlePreview(row) {      var previewServerUrl  row.previewServerUrl;      var fileUrl  row.fileUrl;      //分别获取预览服务地址和预览参数的地址然后拼接      //预览文件url地址需要使用Base64编码URL      let url         previewServerUrl  encodeURIComponent(Base64.encodeURI(fileUrl));      window.open(url);    },    // 下载    handleDownload(row) {      var filePath  row.filePath;      var fileName  row.fileName;      var url         this.downloadUrl  ?filePath  filePath  &fileName  fileName;      const a  document.createElement(a);      a.setAttribute(download, fileName);      a.setAttribute(target, _blank);      a.setAttribute(href, url);      a.click();    },    /** 提交按钮 */    submitForm() {      this.$refs[form].validate((valid) > {        if (valid) {          if (this.form.id ! null) {            updatePreview(this.form).then((response) > {              this.msgSuccess(修改成功);              this.open  false;              this.fileList  [];              this.getList();            });          } else {            addPreview(this.form).then((response) > {              this.msgSuccess(新增成功);              this.open  false;              this.fileList  [];              this.getList();            });          }        }      });    },    /** 删除按钮操作 */    handleDelete(row) {      const ids  row.id || this.ids;      this.$confirm(是否确认删除文件编号为  ids  的数据项?, 警告, {        confirmButtonText: 确定,        cancelButtonText: 取消,        type: warning,      })        .then(function () {          return delPreview(ids);        })        .then(() > {          this.getList();          this.msgSuccess(删除成功);        });    },    // 文件上传失败    uploadError(err) {      this.btnLoding  false;      this.$message.error(res.msg);    },    // 上传中    uploadProgress(e) {      this.btnLoding  true;    },    // 文件上传之前    beforeUpload(file) {      const fileName  file.name;      const fileType  fileName.substring(fileName.lastIndexOf(.));      const whiteList  [        .doc,        .docx,        .xls,        .xlsx,        .ppt,        .pptx,        .pdf,        .mp3,        .mp4,        .wav,      ];      //array.indexOf此方法判断数组中是否存在某个值如果存在返回数组元素的下标否则返回-1。      if (whiteList.indexOf(fileType)  -1) {        this.$message.error(只允许如下文件类型:  whiteList.toString());        return false;        // 不处理      } else {        this.form.fileName  file.name;      }    },    // 文件上传成功    uploadSuccess(res, file, fileList) {      this.form.previewServerUrl  res.previewServerUrl;      this.form.fileUrl  res.fileUrl;      this.form.filePath  res.filePath;      this.btnLoding  false;      this.fileList  fileList;      this.$message(res.msg);    },    beyond(file, fileList) {      this.$message({        message: 最多上传一个文件,        type: warning,      });    },    // 移除选择的文件    fileRemove(file, fileList) {      this.btnLoding  false;      this.reset();      this.fileList  [];    },  },};</script>

后台Controller完整代码

package com.ruoyi.web.controller.fzys.basicinfomannager;import com.ruoyi.common.annotation.Log;import com.ruoyi.common.config.RuoYiConfig;import com.ruoyi.common.constant.Constants;import com.ruoyi.common.constant.HttpStatus;import com.ruoyi.common.core.controller.BaseController;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.core.domain.fzys.basicinfomanage.BusFilePreview;import com.ruoyi.common.core.page.TableDataInfo;import com.ruoyi.common.enums.BusinessType;import com.ruoyi.common.utils.DateUtils;import com.ruoyi.common.utils.StringUtils;import com.ruoyi.common.utils.UploadUtil;import com.ruoyi.common.utils.poi.ExcelUtil;import com.ruoyi.framework.config.ServerConfig;import com.ruoyi.fzys.service.basicinfomanageService.IBusFilePreviewService;import com.ruoyi.system.utils.FileUtils;import com.ruoyi.web.controller.fzys.config.PreviewConfig;import io.swagger.annotations.ApiOperation;import org.apache.ibatis.annotations.Param;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.util.List;/** * previewController * * author ruoyi * date 2021-10-29 */RestControllerRequestMapping(/fzys/basicinfomanage/preview)public class BusFilePreviewController extends BaseController{    /**允许上传的格式*/    private static String[] allowFiles  {.doc, .docx, .xls, .xlsx, .ppt, .pptx, .pdf,.mp3,.mp4,.wav    };    Autowired    private ServerConfig serverConfig;    Autowired    private PreviewConfig previewConfig;    Autowired    private IBusFilePreviewService busFilePreviewService;    PostMapping(/uploadPreviewFile)    public AjaxResult uploadPreviewFile(Param(file) MultipartFile file) {        AjaxResult ajaxResult  AjaxResult.success();        try {            String path  RuoYiConfig.getUploadPath()  /  DateUtils.datePath()  /;            FileUtils.check_folder(path);            String auth_file_name  UploadUtil.save_file_withAllow(file, path ,allowFiles);            if (StringUtils.isEmpty(auth_file_name)){                return AjaxResult.error(HttpStatus.BAD_REQUEST, 文件格式不合法);            }            ajaxResult.put(code, 200);            ajaxResult.put(message, 成功);            ajaxResult.put(fileName, auth_file_name);            ajaxResult.put(filePath, path  auth_file_name);            String fileUrl  serverConfig.getUrl() Constants.RESOURCE_PREFIX  RuoYiConfig.getUploadPathPre()  File.separator  DateUtils.datePath()  File.separator  auth_file_name;            String previewServerUrl  Constants.HTTP  previewConfig.getServerIp() : previewConfig.getServerPort()  Constants.PREVIEW_SERVER_URL;            ajaxResult.put(previewServerUrl, previewServerUrl);            ajaxResult.put(fileUrl, fileUrl);        } catch (IOException e) {            ajaxResult.put(code, 400);            ajaxResult.put(message, 上传失败);            e.printStackTrace();        }        return ajaxResult;    }    /**     * 下载文件     * param fileName     * param response     * throws IOException     */    GetMapping(download)    ApiOperation(下载)    public void downloadFile(String filePath,String fileName, HttpServletResponse response) throws IOException {        File file  new File(filePath);        // 清空response        response.reset();        // 设置response的Header 通知浏览器 已下载的方式打开文件 防止文本图片预览        response.addHeader(Content-Disposition,                attachment;filename  new String(fileName.getBytes(gbk), iso-8859-1)); // 转码之后下载的文件不会出现中文乱码        response.addHeader(Content-Length,   file.length());        // 以流的形式下载文件        InputStream fis  new BufferedInputStream(new FileInputStream(filePath));        byte[] buffer  new byte[fis.available()];        fis.read(buffer);        fis.close();        OutputStream toClient  new BufferedOutputStream(response.getOutputStream());        toClient.write(buffer);        toClient.flush();        toClient.close();    }    /**     * 查询preview列表     */    GetMapping(/list)    public TableDataInfo list(BusFilePreview busFilePreview)    {        startPage();        List<BusFilePreview> list  busFilePreviewService.selectBusFilePreviewList(busFilePreview);        return getDataTable(list);    }    /**     * 导出preview列表     */    Log(title  preview, businessType  BusinessType.EXPORT)    PostMapping(/export)    public void export(HttpServletResponse response, BusFilePreview busFilePreview) throws IOException    {        List<BusFilePreview> list  busFilePreviewService.selectBusFilePreviewList(busFilePreview);        ExcelUtil<BusFilePreview> util  new ExcelUtil<BusFilePreview>(BusFilePreview.class);        util.exportExcel(response, list, preview);    }    /**     * 获取preview详细信息     */    GetMapping(value  /{id})    public AjaxResult getInfo(PathVariable(id) Long id)    {        return AjaxResult.success(busFilePreviewService.selectBusFilePreviewById(id));    }    /**     * 新增preview     */    Log(title  preview, businessType  BusinessType.INSERT)    PostMapping    public AjaxResult add(RequestBody BusFilePreview busFilePreview) throws IOException{        if (StringUtils.isNull(busFilePreview.getFileName())) {            AjaxResult.error(缺少文件名称);        }        return toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));    }    /**     * 修改preview     */    Log(title  preview, businessType  BusinessType.UPDATE)    PutMapping    public AjaxResult edit(RequestBody BusFilePreview busFilePreview)    {        return toAjax(busFilePreviewService.updateBusFilePreview(busFilePreview));    }    /**     * 删除preview     */    Log(title  preview, businessType  BusinessType.DELETE) DeleteMapping(/{ids})    public AjaxResult remove(PathVariable Long[] ids)    {        return toAjax(busFilePreviewService.deleteBusFilePreviewByIds(ids));    }}

后台其他各层代码均为根据表结构代码生成。

问题

1、注意后台需要放开下载接口的鉴权

2、如果在预览时页面显示

Whitelabel Error Page

找到kkFileView目录下log下kkFileView.log文件查看具体报错

Illegal base64 character 3a

 

这是因为一开始没将预览文件url进行Base64编码导致。

3、上传文件时提示

Maximum upload size exceeded:nested exception is java.lang.lllegalStateException:

org.apache.tomcat.util.http.fileupload.FileSizeLimitExceeededException:

The fiel filed exceeds its maximum perrmitted size of xxx bytes

 

找到application.yml中修改如下配置

# Spring配置spring:  # 资源信息  messages:    # 国际化资源文件路径    basename: i18n/messages  profiles:    active: druid  # 文件上传  servlet:     multipart:       # 单个文件大小       max-file-size:  100MB       # 设置总上传的文件大小       max-request-size:  200MB

修改位置

 

标签:
声明:无特别说明,转载请标明本文来源!