apache添加多个网站/营销推广的主要方法
场景
SpringBoot+Vue+OpenOffice实现文档管理(文档上传、下载、在线预览):
SpringBoot+Vue+OpenOffice实现文档管理(文档上传、下载、在线预览)_霸道流氓气质的博客-CSDN博客_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,双击启动即可
启动成功之后访问:
http://127.0.0.1:8012/index
出现如下界面则成功
项目接入使用
当您的项目内需要预览文件时,只需要调用浏览器打开本项目的预览接口,并传入须要预览文件的url
var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(base64Encode(url)));
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
建表与后台SpringBoot代码生成
若依前后端分离版本地搭建开发环境并运行项目的教程:
若依前后端分离版手把手教你本地搭建环境并运行项目_霸道流氓气质的博客-CSDN博客_运行若依分离版
基于上面搭建起来架构的基础上。
设计数据库表
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;}@Overridepublic 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 :title="title" :visible.sync="open" width="35%" append-to-body><el-form ref="form" :model="form" :rules="rules" label-width="110px"><el-form-item label="文件名" prop="fileName"><el-inputv-model="form.fileName"placeholder="请输入文件名"disabled/></el-form-item><el-form-item label="附件" prop="photoPath"><el-upload:headers="headers":action="url":multiple="false":file-list="fileList":on-remove="fileRemove":on-success="uploadSuccess":on-error="uploadError":on-progress="uploadProgress":before-upload="beforeUpload":limit="1":on-exceed="beyond"><el-button size="small">上传<i class="el-icon-upload el-icon--right"></i></el-button><div class="el-upload__tip" style="color: red" slot="tip">提示:仅允许导入".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",".pdf", ".mp3",".mp4",".wav"格式文件!</div></el-upload></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</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为http://127.0.0.1:8012/onlinePreview?url=
文件预览url为调用kkFileView预览时传递的参数,比如
http://127.0.0.1:9090/profile/upload/2022/12/10/a28ffa19-9982-42d2-8766-1feb274c5bb7.doc
文件磁盘路径映射为网络url可以参考
SpringBoot中通过重写WebMvcConfigurer的方法配置静态资源映射实现图片上传后返回网络Url:
SpringBoot中通过重写WebMvcConfigurer的方法配置静态资源映射实现图片上传后返回网络Url_霸道流氓气质的博客-CSDN博客
这里后台将预览文件的网络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.docString 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() http://127.0.0.1:9090//Constants.RESOURCE_PREFIX /profile//RuoYiConfig.getUploadPathPre() /upload//File.separator ///DateUtils.datePath() /2022/12/10//auth_file_name a28ffa19-9982-42d2-8766-1feb274c5bb7.doc//url http://127.0.0.1:9090/profile/upload/2022/12/10/a28ffa19-9982-42d2-8766-1feb274c5bb7.docString 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 filename=file.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_temp=new 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() http://127.0.0.1:9090//Constants.RESOURCE_PREFIX /profile//RuoYiConfig.getUploadPathPre() /upload//File.separator ///DateUtils.datePath() /2022/12/10//auth_file_name a28ffa19-9982-42d2-8766-1feb274c5bb7.doc//url http://127.0.0.1:9090/profile/upload/2022/12/10/a28ffa19-9982-42d2-8766-1feb274c5bb7.docString 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.1serverPort: 8012
然后新增配置文件获取
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(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为
http://127.0.0.1:8012/onlinePreview?url=
上传成功之后,前端获取返回参数并赋值到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);// 清空responseresponse.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编码URLlet 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 class="app-container"><el-form:model="queryParams"ref="queryForm":inline="true"v-show="showSearch"label-width="68px"><el-form-item label="文件名" prop="fileName"><el-inputv-model="queryParams.fileName"placeholder="请输入文件名"clearablesize="small"@keyup.enter.native="handleQuery"/></el-form-item><el-form-item><el-buttontype="cyan"icon="el-icon-search"size="mini"@click="handleQuery">搜索</el-button><el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button></el-form-item></el-form><el-row :gutter="10" class="mb8"><el-col :span="1.5"><el-buttontype="primary"icon="el-icon-plus"size="mini"@click="handleAdd"v-hasPermi="['basicinfomanage:preview:add']">新增</el-button></el-col><el-col :span="1.5"><el-buttontype="success"icon="el-icon-edit"size="mini":disabled="single"@click="handleUpdate"v-hasPermi="['basicinfomanage:preview:edit']">修改</el-button></el-col><el-col :span="1.5"><el-buttontype="danger"icon="el-icon-delete"size="mini":disabled="multiple"@click="handleDelete"v-hasPermi="['basicinfomanage:preview:remove']">删除</el-button></el-col><right-toolbar:showSearch.sync="showSearch"@queryTable="getList"></right-toolbar></el-row><el-tablev-loading="loading":data="previewList"@selection-change="handleSelectionChange"><el-table-column type="selection" width="55" align="center" /><el-table-columnshow-overflow-tooltiplabel="文件名"align="center"prop="fileName"/><el-table-columnlabel="操作"align="center"class-name="small-padding fixed-width"width="200"><template slot-scope="scope"><el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handleUpdate(scope.row)"v-hasPermi="['basicinfomanage:preview:edit']">修改</el-button><el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handlePreview(scope.row)">预览</el-button><el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handleDownload(scope.row)">下载</el-button><el-buttonsize="mini"type="text"icon="el-icon-delete"@click="handleDelete(scope.row)"v-hasPermi="['basicinfomanage:preview:remove']">删除</el-button></template></el-table-column></el-table><paginationv-show="total > 0":total="total":page.sync="queryParams.pageNum":limit.sync="queryParams.pageSize"@pagination="getList"/><!-- 添加或修改preview对话框 --><el-dialog :title="title" :visible.sync="open" width="35%" append-to-body><el-form ref="form" :model="form" :rules="rules" label-width="110px"><el-form-item label="文件名" prop="fileName"><el-inputv-model="form.fileName"placeholder="请输入文件名"disabled/></el-form-item><el-form-item label="附件" prop="photoPath"><el-upload:headers="headers":action="url":multiple="false":file-list="fileList":on-remove="fileRemove":on-success="uploadSuccess":on-error="uploadError":on-progress="uploadProgress":before-upload="beforeUpload":limit="1":on-exceed="beyond"><el-button size="small">上传<i class="el-icon-upload el-icon--right"></i></el-button><div class="el-upload__tip" style="color: red" slot="tip">提示:仅允许导入".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",".pdf", ".mp3",".mp4",".wav"格式文件!</div></el-upload></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</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编码URLlet 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*/
@RestController
@RequestMapping("/fzys/basicinfomanage/preview")
public class BusFilePreviewController extends BaseController
{/**允许上传的格式*/private static String[] allowFiles = {".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf",".mp3",".mp4",".wav"};@Autowiredprivate ServerConfig serverConfig;@Autowiredprivate PreviewConfig previewConfig;@Autowiredprivate 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);// 清空responseresponse.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)@PostMappingpublic 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)@PutMappingpublic 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/messagesprofiles:active: druid# 文件上传servlet:multipart:# 单个文件大小max-file-size: 100MB# 设置总上传的文件大小max-request-size: 200MB
修改位置
完整示例代码下载地址:
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/88849140
相关文章:

SpringBoot+Vue+kkFileView实现文档管理(文档上传、下载、在线预览)
场景 SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览): SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览)_霸道流氓气质的博客-CSDN博客_vue openoffice 上面在使用OpenOffice实现doc、excel、ppt等文档的管理和预览。 除此之外…...

从代码层面熟悉UniAD,开始学习了解端到端整体架构
0. 简介 最近端到端已经是越来越火了,以UniAD为代表的很多工作不断地在不断刷新端到端的指标,比如最近SparseDrive又重新刷新了所有任务的指标。在端到端火热起来之前,成熟的模块化自动驾驶系统被分解为不同的独立任务,例如感知、…...

微信小程序-选中文本时选中checkbox
1.使用labe嵌套住checkbox标签 <label class"label-box"> <checkbox >匿名提交</checkbox> </label>2.使checkbox和label组件在同一行 .label-box{display: flex;align-items: center; }效果图 此时选中文本匿名提交,checkbox…...

[玄机]流量特征分析-蚁剑流量分析
题目网址【玄机】:https://xj.edisec.net/ AntSword(蚁剑)是一款开源的网络安全工具,常用于网络渗透测试和攻击。它可以远程连接并控制被攻击计算机,执行命令、上传下载文件等操作。 蚁剑与网站进行数据交互的过程中&a…...

2-51 基于matlab的IFP_FCM(Improved fuzzy partitions-FCM)
基于matlab的IFP_FCM(Improved fuzzy partitions-FCM),改进型FCM(模糊C均值)聚类算法,解决了FCM算法对初始值设定较为敏感、训练速度慢、在迭代时容易陷入局部极小的问题。并附带了Box和Jenkins煤气炉数据模型辨识实例。程序已调通࿰…...

Java人力资源招聘社会校招类型招聘小程序
✨💼【职场新风尚!解锁人力资源招聘新神器:社会校招类型招聘小程序】✨ 🎓【校招新体验,一键触达梦想企业】🎓 还在为错过校园宣讲会而懊恼?别怕,社会校招类型招聘小程序来救场&am…...

oracle表、表空间使用空间
文章目录 一、Oracle查询表空间占用情况二、Oracle查询表占用的空间三、Oracle查询表空间使用情况四、Oracle查询每张表占用空间五、表空间大小 TOC 一、Oracle查询表空间占用情况 oracle日常工作中查看表占用空间大小是数据库管理中的基本操作: SELECT a.tablesp…...

IDEA管理远程仓库Git
1、模拟项目 新建一个文件夹,用来这次演示 用IDEA来打开文件夹 2、创建仓库 在IDEA中给该文件夹创建本地仓库和远程仓库 在菜单栏找到VCS选择Share project on Gitee 在弹窗中输入描述信息 接下来会出现以下弹窗 点击ADD后,在gitee上会创建远程仓库 …...
【数据结构】Java实现二叉搜索树
二叉搜索树的基本性质 二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树,它具有以下特征: 1. 节点结构:每个节点包含一个键(key)和值(value),以及指…...

钉钉小程序如何通过setdate重置对象
在钉钉小程序中,通过setData方法来重置对象(即更新对象中的数据)是一个常见的操作。然而,需要注意的是,钉钉小程序(或任何小程序平台)的setData方法在处理对象更新时有一些特定的规则和最佳实践…...

DjangoRF-10-过滤-django-filter
1、安装pip install django-filter https://pypi.org/ 搜索django-filter基础用法 2、进行配置 3、进行内容调试。 4、如果碰到没有关联的字段。interfaces和projects没有直接关联字段,但是interface和module有关联,而且module和projects关联&#x…...

Android SurfaceFlinger——GraphicBuffer的生成(三十二)
通过前面的学习我们知道,在 SurfaceFlinger 中使用的生产者/消费者模型,Surface 做为生产者一方存在如下两个比较重要的函数: dequeueBuffer:获取一个缓冲区(GraphicBuffer),也就是 GraphicBuffer 生成。queueBuffer :把缓冲区(GraphicBuffer)放入缓冲队列中。 …...

<数据集>棉花识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:13765张 标注数量(xml文件个数):13765 标注数量(txt文件个数):13765 标注类别数:4 标注类别名称:[Partially opened, Fully opened boll, Defected boll, Flower] 序…...

[240730] OpenAI 推出基于规则的奖励机制 (RBR) 提升模型安全性 | 英特尔承认其13、14代 CPU 存在问题
目录 OpenAI 推出基于规则的奖励机制(RBR)提升模型安全性英特尔承认其 13、14代 CPU 存在问题 OpenAI 推出基于规则的奖励机制(RBR)提升模型安全性 为了解决传统强化学习中依赖人工反馈的低效问题,OpenAI 开发了基于规…...

【JavaScript】展开运算符详解
文章目录 一、展开运算符的基本用法1. 展开数组2. 展开对象 二、展开运算符的实际应用1. 合并数组2. 数组的浅拷贝3. 合并对象4. 对象的浅拷贝5. 更新对象属性 三、展开运算符的高级用法1. 在函数参数中使用2. 嵌套数组的展开3. 深拷贝对象4. 动态属性名 四、注意事项和最佳实践…...

麒麟V10系统统一认证子系统国际化
在适配麒麟V10系统统一认证子系统国际化过程中, 遇到了很多的问题,关键是麒麟官方的文档对这部分也是粗略带过,遇到的问题有: (1)xgettext无法提取C源文件中目标待翻译的字符串。 (2)使用msgf…...

C语言进阶 13. 文件
C语言进阶 13. 文件 文章目录 C语言进阶 13. 文件13.1. 格式化输入输出13.2. 文件输入输出13.3. 二进制文件13.4. 按位运算13.5. 移位运算13.6. 位运算例子13.7. 位段 13.1. 格式化输入输出 格式化输入输出: printf %[flags][width][.prec][hlL]type scanf %[flags]type %[fl…...

LinuxCentos中ELK日志分析系统的部署(详细教程8K字)附图片
🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理防护和群集专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作…...

Vscode ssh Could not establish connection to
错误表现 上午还能正常用vs code连接服务器看代码,中午吃个饭关闭vscode再重新打开输入密码后就提示 Could not establish connection to xxxx 然后我用终端敲ssh的命令连接,结果是能正常连接。 解决方法 踩坑1 网上直接搜Could not establish con…...

数字陷波器的设计和仿真(Matlab+C)
目录 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 2. 示例2 三、C语言仿真 1. 由系统函数计算差分方程 2. 示例代码 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 clear clc f0=100;%滤掉的100Hz fs=1000;%大于两倍的信号最高频率 r=0.9; w0=2*pi*f0/fs;%转换到…...

[玄机]流量特征分析-常见攻击事件 tomcat
题目网址【玄机】:https://xj.edisec.net/ Tomcat是一个开源的Java Servlet容器,它实现了Java Servlet和JavaServer Pages (JSP) 技术,提供了一个运行这些应用程序的Web服务器环境。Tomcat由Apache软件基金会的Jakarta项目开发,是…...

【TOOLS】Project 2 Maven Central
发布自己的项目到maven中央仓库 Maven Central Account 访问:https://central.sonatype.com/,点击右上角,根据提示注册账号 构建User token ,用于访问中央仓库的API: 点击右上角,查看账户点击Generate Us…...

【Opencv】模糊
消除噪声 用该像素周围的平均值代替该像素值 4个函数 blur():最经典的 import os import cv2 img cv2.imread(os.path.join(.,dog.jpg)) k_size 7 #窗口大小,数字越大,模糊越强 img_blur cv2.blur(img,(k_size,k_size)) #窗口是正方形ÿ…...

函数式编程范式
文章目录 函数式编程范式不可变性(Immutable)纯函数(Pure Functions)函数作为一等公民(First-Class Functions)高阶函数(Higher-Order Functions函数组合(Function Composition&…...

特征缩放的秘籍:sklearn中的数据标准化技术
特征缩放的秘籍:sklearn中的数据标准化技术 在机器学习中,特征缩放(Feature Scaling)是数据预处理的重要步骤,它确保了不同量纲和范围的特征在模型训练中具有相同的重要性。Scikit-learn(简称sklearn&…...

hdfs文件系统
简述什么是HDFS,以及HDFS作用 ? HDFS在Hadoop中的作用是为海量的数据提供了存储,能提供高吞吐量的数据访问,HDFS有高容错性的 特点,并且设计用来部署在低廉的硬件上;而且它提供高吞吐量来访问应用程序的数…...

基于STM32设计的个人健康检测仪(华为云IOT)(191)
基于STM32设计的个人健康检测仪(华为云IOT)(191) 文章目录 一、设计需求1.1 设计需求总结1.2 设计思路【1】整体设计思路【2】整体构架【3】ESP8266模块配置【4】上位机开发思路【5】供电方式1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】课题研究的意义【…...

面试:CUDA Tiling 和 CPU tiling 技术详解
目录 一、CUDA Tiling 和 CPU Tiling 技术概述 (一)技术原理 (二)应用场景 (三)优势和劣势 二、Tiling 技术在深度学习中的应用 三、Tiling 技术的缺点 一、CUDA Tiling 和 CPU Tiling 技术概述 Til…...

SQL语句中,`TRUNCATE` 和 `DELETE`的区别
TRUNCATE 和 DELETE 是 SQL 中用于删除表中数据的两种命令,它们有一些关键区别: 1. 基本区别 DELETE: 删除表中的数据,但不会删除表结构和索引。可以使用 WHERE 子句来删除特定的记录,也可以不使用 WHERE 子句来删除所有记录。会…...

【Git】.gitignore全局配置与忽略匹配规则详解
设置全局配置 1)在C:/Users/用户名/目录下创建.gitignore文件,在里面添加忽略规则。 如何创建 .gitignore 文件? 新建一个.txt文件,重命名(包括后缀.txt)为 .gitignore 即可。 2)将.gitignore设…...