场景

SpringBoot集成OpenOffice实现doc文档转html:

SpringBoot集成OpenOffice实现doc文档转html_BADAO_LIUMANG_QIZHI的博客-CSDN博客

在上面初步使用了OpenOffice之后,怎样实现文档管理,文档上传、下载、在线预览等。

首先OpenOffice的下载安装与启动服务参照上文,不再复述。

注:

博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、搭建SpringBoot+Vue前后端分离项目

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

若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客

2、设计表

数据库语句为

DROP TABLE IF EXISTS `bus_file_preview`;
CREATE TABLE `bus_file_preview`  (`id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键',`fileName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '原文件名(上传前文件名)',`fileType` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件后缀(.xls;.xlsx;.ppt;.doc;.docx;.pptx)',`uploadPath` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传后文件路径',`uploadFileName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传后文件名',`pdfPath` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '转换pdf路径',`pdfName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '转换pdf文件名',`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 '备注',`preview_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '预览URL',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文件上传与预览' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

依照此表生成前后端代码,然后修改代码。

3、文件上传实现

前端按钮

        <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"accept=".doc,.docx,.xls,.ppt,.xlsx,.pptx"><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、.ppt、.xlsx、.pptx”格式文件!</div></el-upload></el-form-item>

调用的各方法

    // 文件上传失败uploadError(err) {this.btnLoding = false;this.$message.error(res.msg);},// 上传中uploadProgress(e) {this.btnLoding = true;},// 文件上传之前beforeUpload(file) {console.log(file, "上传之前");const fileName = file.name;const fileType = fileName.substring(fileName.lastIndexOf("."));if (fileType === ".doc" ||fileType === ".docx" ||fileType === ".xls" ||fileType === ".ppt" ||fileType === ".pptx" ||fileType === ".xlsx") {this.form.filename = file.name;// 不处理} else {this.$message.error("请上传正确的文件类型,.doc,.docx,.xls,.ppt,.xlsx,.pptx,");return false;}},// 文件上传成功uploadSuccess(res, file, fileList) {this.form.uploadpath = res.uploadpath;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 = [];},

对应后台SpingBoot通用上传接口

这里做了修改,使其能返回磁盘路径

    /*** 通用上传请求返回磁盘路径*/@PostMapping("/common/uploadWithAbsolutePath")public AjaxResult uploadFileWithAbsolutePath(MultipartFile file) throws Exception{try{// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称String fileName = FileUploadUtils.uploadWithAbsolutePath(filePath, file);AjaxResult ajax = AjaxResult.success();ajax.put("uploadpath", filePath+ File.separator+fileName);return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}}

调用的方法uploadWithAbsolutePath实现

    public static final String uploadWithAbsolutePath(String baseDir, MultipartFile file) throws IOException{try{return uploadWithAbsolutePath(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);}catch (Exception e){throw new IOException(e.getMessage(), e);}}

其中又调用的uploadWithAbsolutePath方法实现

    public static final String uploadWithAbsolutePath(String baseDir, MultipartFile file, String[] allowedExtension)throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,InvalidExtensionException{int fileNamelength = file.getOriginalFilename().length();if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH){throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);}assertAllowed(file, allowedExtension);String fileName = extractFilename(file);File desc = getAbsoluteFile(baseDir, fileName);file.transferTo(desc);return fileName;}

其他的若依框架原来的方法。

上传效果

4、预览实现

上传之后的文件转换成pdf的实现,在提交按钮时调用后台就接口

    /** 提交按钮 */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();});}}});},

首先是新增接口

    /*** 新增preview*/@Log(title = "preview", businessType = BusinessType.INSERT)@PostMappingpublic AjaxResult add(@RequestBody BusFilePreview busFilePreview) throws IOException{if (StringUtils.isNull(busFilePreview.getFilename())) {AjaxResult.error("缺少文件名称");}if (StringUtils.isNull(busFilePreview.getUploadpath())) {AjaxResult.error("缺少上传文件路径");}String substringAfter = StringUtils.substringAfter(busFilePreview.getUploadpath(), ".");String upName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setUploadfilename(upName);busFilePreview.setFiletype(substringAfter); //类型if ("pdf".equals(substringAfter)){FilePdfUtils.copyFile(busFilePreview.getUploadpath(), RuoYiConfig.getProfile());String pdfName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setPdfpath(RuoYiConfig.getProfile()+ "/" + pdfName);busFilePreview.setPdfname(pdfName);return  toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));}File file = new File(busFilePreview.getUploadpath());FileInputStream fileInputStream = new FileInputStream(file);String htmFileName = FilePdfUtils.file2pdf(fileInputStream, substringAfter,RuoYiConfig.getProfile());String pdfPath = RuoYiConfig.getProfile()+ "/" + htmFileName;busFilePreview.setPdfpath(pdfPath);String pdfName = StringUtils.substringAfterLast(pdfPath, "/");busFilePreview.setPdfname(pdfName);String previewUrl = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX+File.separator+htmFileName;busFilePreview.setPreviewUrl(previewUrl);return toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));}

这里调用了工具类中FilePdfUtils的file2pdf方法,并且将转换后的pdf的路径拼接成静态资源映射后的路径返回给前端。

关于静态资源映射可以参考如下

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

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

5、FilePdfUtils工具类实现

package com.ruoyi.common.utils.pdf;import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import com.ruoyi.common.utils.StringUtils;import java.io.*;
import java.net.ConnectException;
import java.text.SimpleDateFormat;
import java.util.Date;public class FilePdfUtils {/*** 转换文件成pdf** @param fromFileInputStream:* @throws IOException*/public static String file2pdf(InputStream fromFileInputStream, String type,String pdfPath) throws IOException {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String timesuffix = sdf.format(date);String docFileName = null;String htmFileName = null;if("doc".equals(type)){docFileName = "doc_" + timesuffix + ".doc";htmFileName = "doc_" + timesuffix + ".pdf";}else if("docx".equals(type)){docFileName = "docx_" + timesuffix + ".docx";htmFileName = "docx_" + timesuffix + ".pdf";}else if("xls".equals(type)){docFileName = "xls_" + timesuffix + ".xls";htmFileName = "xls_" + timesuffix + ".pdf";}else if("ppt".equals(type)){docFileName = "ppt_" + timesuffix + ".ppt";htmFileName = "ppt_" + timesuffix + ".pdf";}else if("xlsx".equals(type)){docFileName = "xlsx_" + timesuffix + ".xlsx";htmFileName = "xlsx_" + timesuffix + ".pdf";}else if("pptx".equals(type)){docFileName = "pptx_" + timesuffix + ".pptx";htmFileName = "pptx_" + timesuffix + ".pdf";}else{return null;}check_folder(pdfPath);File htmlOutputFile = new File(pdfPath + File.separatorChar + htmFileName);File docInputFile = new File(pdfPath + File.separatorChar + docFileName);if (htmlOutputFile.exists())htmlOutputFile.delete();htmlOutputFile.createNewFile();if (docInputFile.exists())docInputFile.delete();docInputFile.createNewFile();/*** 由fromFileInputStream构建输入文件*/try {OutputStream os = new FileOutputStream(docInputFile);int bytesRead = 0;byte[] buffer = new byte[1024 * 8];while ((bytesRead = fromFileInputStream.read(buffer)) != -1) {os.write(buffer, 0, bytesRead);}os.close();fromFileInputStream.close();} catch (IOException e) {}OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);try {connection.connect();} catch (ConnectException e) {System.err.println("文件转换出错,请检查OpenOffice服务是否启动。");}DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection);converter.convert(docInputFile, htmlOutputFile);connection.disconnect();// 转换完之后删除word文件docInputFile.delete();System.out.println(htmFileName);return htmFileName;}public static void check_folder(String path) {File dir = new File(path);// 判断文件夹是否存在if (dir.isDirectory()) {} else {dir.mkdirs();}}public static void copyFile(String oldPath, String newPath) throws IOException {File oldFile = new File(oldPath);//获取旧的文件File对象File file = new File(newPath + oldFile.separator + StringUtils.substringAfterLast(oldPath, "/"));  //获取新的文件File对象并生成文件FileInputStream in = new FileInputStream(oldFile);  //FileOutputStream out = new FileOutputStream(file);byte[] buffer=new byte[2097152];int readByte = 0;//读取旧文件的流写入新文件里while((readByte = in.read(buffer)) != -1){out.write(buffer, 0, readByte);}in.close();out.close();}}

注意这里的连接openOffice的服务的端口要对应并且确保openOffice已经启动

然后工具类FilePdfUtils是在common模块下,所以后台需要在此模块下pom文件中添加依赖

        <dependency><groupId>com.artofsolving</groupId><artifactId>jodconverter</artifactId><version>2.2.1</version></dependency>

添加位置

注意这里的版本为2.2.1,Maven中央仓库中此为最高版本

这里在调用工具类转换文件时,如果文件类型为docx、pptx、xlsx时会报错提示

unknown document format for file ....docx

这是因为2.2.1的能转换doc ,但2.2.2才能转换docx,如果你用2.2.1的jar包,转换2.2.2的docx文档就会出错

除了不加载Maven中央仓库的2.1的依赖之外,还可以重写DocumentFormatRegistry接口的getFormatByFileExtension方法

注意包名一致

package com.artofsolving.jodconverter;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** @ClassName: online* @description: 重写 BasicDocumentFormatRegistry 文档格式* @Author: yandongfa* @Data: 2020-03-24 19:47* @Version: 1.0**/
public class BasicDocumentFormatRegistry implements DocumentFormatRegistry {private List/* <DocumentFormat> */ documentFormats = new ArrayList();public void addDocumentFormat(DocumentFormat documentFormat) {documentFormats.add(documentFormat);}protected List/* <DocumentFormat> */ getDocumentFormats() {return documentFormats;}/*** @param extension*            the file extension* @return the DocumentFormat for this extension, or null if the extension*         is not mapped*/public DocumentFormat getFormatByFileExtension(String extension) {if (extension == null) {return null;}//new DefaultDocumentFormatRegistry();//将文件名后缀统一转化if (extension.indexOf("doc") >= 0) {extension = "doc";}if (extension.indexOf("ppt") >= 0) {extension = "ppt";}if (extension.indexOf("xls") >= 0) {extension = "xls";}String lowerExtension = extension.toLowerCase();for (Iterator it = documentFormats.iterator(); it.hasNext();) {DocumentFormat format = (DocumentFormat) it.next();if (format.getFileExtension().equals(lowerExtension)) {return format;}}return null;}public DocumentFormat getFormatByMimeType(String mimeType) {for (Iterator it = documentFormats.iterator(); it.hasNext();) {DocumentFormat format = (DocumentFormat) it.next();if (format.getMimeType().equals(mimeType)) {return format;}}return null;}
}

6、在线预览实现

          <el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handlePreview(scope.row)">预览</el-button>

调用js方法

    // 预览handlePreview(row) {let url = row.previewUrl;window.open(url);},

这里直接打开url这个字段对应的地址即可,url是在进行文件转换成pdf时生成的映射的服务器上的url

String previewUrl = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX+File.separator+htmFileName;

注意这里的预览地址如果有拦截,让在后台配置中放开白名单。

7、文件下载实现

    // 下载handleDownload(row) {const baseURL = process.env.VUE_APP_BASE_APIwindow.location.href = baseURL + "/common/download/resourceeasy?resource=" + encodeURI(row.uploadpath);},

这里直接修改后台的下载本地资源的通用下载方法

    @GetMapping("/common/download/resourceeasy")public void resourceDownloadEasy(String resource, HttpServletRequest request, HttpServletResponse response)throws Exception{try{if (!FileUtils.checkAllowDownload(resource)){throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));}response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, resource);FileUtils.writeBytes(resource, response.getOutputStream());}catch (Exception e){log.error("下载文件失败", e);}}

下载效果

8、各层完整代码

前端完整代码

<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-button type="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-columnshow-overflow-tooltiplabel="上传后文件路径"align="center"prop="uploadpath"/><el-table-columnshow-overflow-tooltiplabel="转换pdf路径"align="center"prop="pdfpath"width="400"/><el-table-columnshow-overflow-tooltiplabel="预览地址"align="center"prop="previewUrl"width="400"/><el-table-column show-overflow-tooltip label="备注" align="center" prop="remark" /><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-input v-model="form.filename" placeholder="请输入文件名" disabled /></el-form-item><el-form-item label="上传后文件路径" prop="uploadpath"><el-input v-model="form.uploadpath" placeholder="请输入上传后文件名" disabled /></el-form-item><el-form-item label="备注" prop="remark"><el-input v-model="form.remark" placeholder="请输入备注"  /></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"accept=".doc,.docx,.xls,.ppt,.xlsx,.pptx"><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、.ppt、.xlsx、.pptx”格式文件!</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/system/preview";
import { getToken } from "@/utils/auth";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,filetype: null,uploadpath: null,pdfpath: null,pdfname: null,},// 表单参数form: {},// 表单校验rules: {filename: [{required: true,message: "文件名称不能为空",trigger: "blur",},],},// 上传按钮闸口btnLoding: false,//  请求头headers: { Authorization: "Bearer" + " " + getToken() },// 上传地址url: process.env.VUE_APP_BASE_API + "/common/uploadWithAbsolutePath",// 图片列表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,uploadpath: 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) {let url = row.previewUrl;window.open(url);},// 下载handleDownload(row) {const baseURL = process.env.VUE_APP_BASE_APIwindow.location.href = baseURL + "/common/download/resourceeasy?resource=" + encodeURI(row.uploadpath);},/** 提交按钮 */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) {console.log(file, "上传之前");const fileName = file.name;const fileType = fileName.substring(fileName.lastIndexOf("."));if (fileType === ".doc" ||fileType === ".docx" ||fileType === ".xls" ||fileType === ".ppt" ||fileType === ".pptx" ||fileType === ".xlsx") {this.form.filename = file.name;// 不处理} else {this.$message.error("请上传正确的文件类型,.doc,.docx,.xls,.ppt,.xlsx,.pptx,");return false;}},// 文件上传成功uploadSuccess(res, file, fileList) {this.form.uploadpath = res.uploadpath;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>

前端js代码

​
import request from '@/utils/request'// 查询preview列表
export function listPreview(query) {return request({url: '/system/preview/list',method: 'get',params: query})
}// 查询preview详细
export function getPreview(id) {return request({url: '/system/preview/' + id,method: 'get'})
}// 新增preview
export function addPreview(data) {return request({url: '/system/preview',method: 'post',data: data})
}// 修改preview
export function updatePreview(data) {return request({url: '/system/preview',method: 'put',data: data})
}// 删除preview
export function delPreview(id) {return request({url: '/system/preview/' + id,method: 'delete'})
}​

后台实体类

package com.ruoyi.system.domain;import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;public class BusFilePreview extends BaseEntity
{private static final long serialVersionUID = 1L;/** 主键 */private Long id;/** 原文件名(上传前文件名) */@Excel(name = "原文件名", readConverterExp = "上传前文件名")private String filename;/** 文件后缀(.xls;.xlsx;.ppt;.doc;.docx;.pptx) */@Excel(name = "文件后缀", readConverterExp = ".=xls;.xlsx;.ppt;.doc;.docx;.pptx")private String filetype;/** 上传后文件路径 */@Excel(name = "上传后文件路径")private String uploadpath;/** 上传后文件名 */@Excel(name = "上传后文件名")private String uploadfilename;/** 转换pdf路径 */@Excel(name = "转换pdf路径")private String pdfpath;/** 转换pdf文件名 */@Excel(name = "转换pdf文件名")private String pdfname;/** 预览地址 */@Excel(name = "预览地址")private String previewUrl;public String getPreviewUrl() {return previewUrl;}public void setPreviewUrl(String previewUrl) {this.previewUrl = previewUrl;}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 setFiletype(String filetype){this.filetype = filetype;}public String getFiletype(){return filetype;}public void setUploadpath(String uploadpath){this.uploadpath = uploadpath;}public String getUploadpath(){return uploadpath;}public void setUploadfilename(String uploadfilename){this.uploadfilename = uploadfilename;}public String getUploadfilename(){return uploadfilename;}public void setPdfpath(String pdfpath){this.pdfpath = pdfpath;}public String getPdfpath(){return pdfpath;}public void setPdfname(String pdfname){this.pdfname = pdfname;}public String getPdfname(){return pdfname;}@Overridepublic String toString() {return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("id", getId()).append("filename", getFilename()).append("filetype", getFiletype()).append("uploadpath", getUploadpath()).append("uploadfilename", getUploadfilename()).append("pdfpath", getPdfpath()).append("pdfname", getPdfname()).append("createTime", getCreateTime()).append("createBy", getCreateBy()).append("updateTime", getUpdateTime()).append("updateBy", getUpdateBy()).append("remark", getRemark()).toString();}
}

后台mapper.xml

​
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.BusFilePreviewMapper"><resultMap type="BusFilePreview" id="BusFilePreviewResult"><result property="id"    column="id"    /><result property="filename"    column="fileName"    /><result property="filetype"    column="fileType"    /><result property="uploadpath"    column="uploadPath"    /><result property="uploadfilename"    column="uploadFileName"    /><result property="pdfpath"    column="pdfPath"    /><result property="pdfname"    column="pdfName"    /><result property="createTime"    column="create_time"    /><result property="createBy"    column="create_by"    /><result property="updateTime"    column="update_time"    /><result property="updateBy"    column="update_by"    /><result property="remark"    column="remark"    /><result property="previewUrl"    column="preview_url"    /></resultMap><sql id="selectBusFilePreviewVo">select id, fileName, fileType, uploadPath, uploadFileName, pdfPath, pdfName, create_time, create_by, update_time, update_by, remark ,preview_url from bus_file_preview</sql><select id="selectBusFilePreviewList" parameterType="BusFilePreview" resultMap="BusFilePreviewResult"><include refid="selectBusFilePreviewVo"/><where><if test="filename != null  and filename != ''"> and fileName like concat('%', #{filename}, '%')</if><if test="filetype != null  and filetype != ''"> and fileType = #{filetype}</if><if test="uploadpath != null  and uploadpath != ''"> and uploadPath = #{uploadpath}</if><if test="uploadfilename != null  and uploadfilename != ''"> and uploadFileName like concat('%', #{uploadfilename}, '%')</if><if test="pdfpath != null  and pdfpath != ''"> and pdfPath = #{pdfpath}</if><if test="pdfname != null  and pdfname != ''"> and pdfName like concat('%', #{pdfname}, '%')</if></where></select><select id="selectBusFilePreviewById" parameterType="Long" resultMap="BusFilePreviewResult"><include refid="selectBusFilePreviewVo"/>where id = #{id}</select><insert id="insertBusFilePreview" parameterType="BusFilePreview" useGeneratedKeys="true" keyProperty="id">insert into bus_file_preview<trim prefix="(" suffix=")" suffixOverrides=","><if test="filename != null">fileName,</if><if test="filetype != null">fileType,</if><if test="uploadpath != null">uploadPath,</if><if test="uploadfilename != null">uploadFileName,</if><if test="pdfpath != null">pdfPath,</if><if test="pdfname != null">pdfName,</if><if test="createTime != null">create_time,</if><if test="createBy != null">create_by,</if><if test="updateTime != null">update_time,</if><if test="updateBy != null">update_by,</if><if test="remark != null">remark,</if><if test="previewUrl != null">preview_url,</if></trim><trim prefix="values (" suffix=")" suffixOverrides=","><if test="filename != null">#{filename},</if><if test="filetype != null">#{filetype},</if><if test="uploadpath != null">#{uploadpath},</if><if test="uploadfilename != null">#{uploadfilename},</if><if test="pdfpath != null">#{pdfpath},</if><if test="pdfname != null">#{pdfname},</if><if test="createTime != null">#{createTime},</if><if test="createBy != null">#{createBy},</if><if test="updateTime != null">#{updateTime},</if><if test="updateBy != null">#{updateBy},</if><if test="remark != null">#{remark},</if><if test="previewUrl != null">#{previewUrl},</if></trim></insert><update id="updateBusFilePreview" parameterType="BusFilePreview">update bus_file_preview<trim prefix="SET" suffixOverrides=","><if test="filename != null">fileName = #{filename},</if><if test="filetype != null">fileType = #{filetype},</if><if test="uploadpath != null">uploadPath = #{uploadpath},</if><if test="uploadfilename != null">uploadFileName = #{uploadfilename},</if><if test="pdfpath != null">pdfPath = #{pdfpath},</if><if test="pdfname != null">pdfName = #{pdfname},</if><if test="createTime != null">create_time = #{createTime},</if><if test="createBy != null">create_by = #{createBy},</if><if test="updateTime != null">update_time = #{updateTime},</if><if test="updateBy != null">update_by = #{updateBy},</if><if test="remark != null">remark = #{remark},</if><if test="previewUrl != null">preview_url = #{previewUrl},</if></trim>where id = #{id}</update><delete id="deleteBusFilePreviewById" parameterType="Long">delete from bus_file_preview where id = #{id}</delete><delete id="deleteBusFilePreviewByIds" parameterType="String">delete from bus_file_preview where id in<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach></delete></mapper>​

后台mapper接口

package com.ruoyi.system.mapper;import com.ruoyi.system.domain.BusFilePreview;import java.util.List;/*** previewMapper接口** @author ruoyi* @date 2021-10-29*/
public interface BusFilePreviewMapper
{/*** 查询preview** @param id previewID* @return preview*/public BusFilePreview selectBusFilePreviewById(Long id);/*** 查询preview列表** @param busFilePreview preview* @return preview集合*/public List<BusFilePreview> selectBusFilePreviewList(BusFilePreview busFilePreview);/*** 新增preview** @param busFilePreview preview* @return 结果*/public int insertBusFilePreview(BusFilePreview busFilePreview);/*** 修改preview** @param busFilePreview preview* @return 结果*/public int updateBusFilePreview(BusFilePreview busFilePreview);/*** 删除preview** @param id previewID* @return 结果*/public int deleteBusFilePreviewById(Long id);/*** 批量删除preview** @param ids 需要删除的数据ID* @return 结果*/public int deleteBusFilePreviewByIds(Long[] ids);
}

后台service接口

package com.ruoyi.system.service;import com.ruoyi.system.domain.BusFilePreview;import java.util.List;/*** previewService接口** @author ruoyi* @date 2021-10-29*/
public interface IBusFilePreviewService
{/*** 查询preview** @param id previewID* @return preview*/public BusFilePreview selectBusFilePreviewById(Long id);/*** 查询preview列表** @param busFilePreview preview* @return preview集合*/public List<BusFilePreview> selectBusFilePreviewList(BusFilePreview busFilePreview);/*** 新增preview** @param busFilePreview preview* @return 结果*/public int insertBusFilePreview(BusFilePreview busFilePreview);/*** 修改preview** @param busFilePreview preview* @return 结果*/public int updateBusFilePreview(BusFilePreview busFilePreview);/*** 批量删除preview** @param ids 需要删除的previewID* @return 结果*/public int deleteBusFilePreviewByIds(Long[] ids);/*** 删除preview信息** @param id previewID* @return 结果*/public int deleteBusFilePreviewById(Long id);
}

后台serviceImpl

package com.ruoyi.system.service.impl;import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.BusFilePreview;
import com.ruoyi.system.mapper.BusFilePreviewMapper;
import com.ruoyi.system.service.IBusFilePreviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** previewService业务层处理** @author ruoyi* @date 2021-10-29*/
@Service
public class BusFilePreviewServiceImpl implements IBusFilePreviewService
{@Autowiredprivate BusFilePreviewMapper busFilePreviewMapper;/*** 查询preview** @param id previewID* @return preview*/@Overridepublic BusFilePreview selectBusFilePreviewById(Long id){return busFilePreviewMapper.selectBusFilePreviewById(id);}/*** 查询preview列表** @param busFilePreview preview* @return preview*/@Overridepublic List<BusFilePreview> selectBusFilePreviewList(BusFilePreview busFilePreview){return busFilePreviewMapper.selectBusFilePreviewList(busFilePreview);}/*** 新增preview** @param busFilePreview preview* @return 结果*/@Overridepublic int insertBusFilePreview(BusFilePreview busFilePreview){busFilePreview.setCreateTime(DateUtils.getNowDate());busFilePreview.setCreateBy(String.valueOf(SecurityUtils.getUsername()));// 创建人return busFilePreviewMapper.insertBusFilePreview(busFilePreview);}/*** 修改preview** @param busFilePreview preview* @return 结果*/@Overridepublic int updateBusFilePreview(BusFilePreview busFilePreview){busFilePreview.setUpdateTime(DateUtils.getNowDate());busFilePreview.setUpdateBy(String.valueOf(SecurityUtils.getUsername()));// 创建人return busFilePreviewMapper.updateBusFilePreview(busFilePreview);}/*** 批量删除preview** @param ids 需要删除的previewID* @return 结果*/@Overridepublic int deleteBusFilePreviewByIds(Long[] ids){return busFilePreviewMapper.deleteBusFilePreviewByIds(ids);}/*** 删除preview信息** @param id previewID* @return 结果*/@Overridepublic int deleteBusFilePreviewById(Long id){return busFilePreviewMapper.deleteBusFilePreviewById(id);}
}

后台Controller

package com.ruoyi.web.controller.system;import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.pdf.FilePdfUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.domain.BusFilePreview;
import com.ruoyi.system.service.IBusFilePreviewService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;/*** previewController** @author ruoyi* @date 2021-10-29*/
@RestController
@RequestMapping("/system/preview")
public class BusFilePreviewController extends BaseController
{@Autowiredprivate IBusFilePreviewService busFilePreviewService;@Autowiredprivate ServerConfig serverConfig;/*** 查询preview列表*/@GetMapping("/list")public TableDataInfo list(BusFilePreview busFilePreview){startPage();List<BusFilePreview> list = busFilePreviewService.selectBusFilePreviewList(busFilePreview);return getDataTable(list);}/*** 获取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("缺少文件名称");}if (StringUtils.isNull(busFilePreview.getUploadpath())) {AjaxResult.error("缺少上传文件路径");}String substringAfter = StringUtils.substringAfter(busFilePreview.getUploadpath(), ".");String upName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setUploadfilename(upName);busFilePreview.setFiletype(substringAfter); //类型if ("pdf".equals(substringAfter)){FilePdfUtils.copyFile(busFilePreview.getUploadpath(), RuoYiConfig.getProfile());String pdfName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setPdfpath(RuoYiConfig.getProfile()+ "/" + pdfName);busFilePreview.setPdfname(pdfName);return  toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));}File file = new File(busFilePreview.getUploadpath());FileInputStream fileInputStream = new FileInputStream(file);String htmFileName = FilePdfUtils.file2pdf(fileInputStream, substringAfter,RuoYiConfig.getProfile());String pdfPath = RuoYiConfig.getProfile()+ "/" + htmFileName;busFilePreview.setPdfpath(pdfPath);String pdfName = StringUtils.substringAfterLast(pdfPath, "/");busFilePreview.setPdfname(pdfName);String previewUrl = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX+File.separator+htmFileName;busFilePreview.setPreviewUrl(previewUrl);return toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));}/*** 修改preview*/@Log(title = "preview", businessType = BusinessType.UPDATE)@PutMappingpublic AjaxResult edit(@RequestBody BusFilePreview busFilePreview) throws IOException {if (StringUtils.isNull(busFilePreview.getFilename())) {AjaxResult.error("缺少文件名称");}if (StringUtils.isNull(busFilePreview.getUploadpath())) {AjaxResult.error("缺少上传文件路径");}String substringAfter = StringUtils.substringAfter(busFilePreview.getUploadpath(), ".");String upName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setUploadfilename(upName);busFilePreview.setFiletype(substringAfter); //类型if ("pdf".equals(substringAfter)){FilePdfUtils.copyFile(busFilePreview.getUploadpath(), RuoYiConfig.getProfile());String pdfName = StringUtils.substringAfterLast(busFilePreview.getUploadpath(), "/");busFilePreview.setPdfpath(RuoYiConfig.getProfile()+ "/" + pdfName);busFilePreview.setPdfname(pdfName);return  toAjax(busFilePreviewService.insertBusFilePreview(busFilePreview));}File file = new File(busFilePreview.getUploadpath());FileInputStream fileInputStream = new FileInputStream(file);String htmFileName = FilePdfUtils.file2pdf(fileInputStream, substringAfter,RuoYiConfig.getProfile());String pdfPath = RuoYiConfig.getProfile()+ "/" + htmFileName;busFilePreview.setPdfpath(pdfPath);String pdfName = StringUtils.substringAfterLast(pdfPath, "/");busFilePreview.setPdfname(pdfName);String previewUrl = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX+File.separator+htmFileName;busFilePreview.setPreviewUrl(previewUrl);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));}@GetMapping("/pdf")@ApiOperation(value = "预览")public void prePDF(Long id, HttpServletRequest request, HttpServletResponse response) throws IOException {BusFilePreview busFilePreview = busFilePreviewService.selectBusFilePreviewById(id);if (StringUtils.isNotNull(busFilePreview) && StringUtils.isNotNull(busFilePreview.getPdfpath())) {File file = new File(busFilePreview.getPdfpath());if (file.exists()) {byte[] data = null;try {FileInputStream input = new FileInputStream(file);data = new byte[input.available()];input.read(data);response.getOutputStream().write(data);input.close();} catch (Exception e) {e.printStackTrace();}} else if (!file.exists()){BusFilePreview filePreview = new BusFilePreview();filePreview.setId(id);filePreview.setRemark("文件不存在");busFilePreviewService.updateBusFilePreview(filePreview);}}}
}

后台通用Controller

package com.ruoyi.web.controller.common;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;import java.io.File;/*** 通用请求处理** @author ruoyi*/
@RestController
public class CommonController
{private static final Logger log = LoggerFactory.getLogger(CommonController.class);@Autowiredprivate ServerConfig serverConfig;/*** 通用下载请求** @param fileName 文件名称* @param delete 是否删除*/@GetMapping("common/download")public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request){try{if (!FileUtils.checkAllowDownload(fileName)){throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));}String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);String filePath = RuoYiConfig.getDownloadPath() + fileName;response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, realFileName);FileUtils.writeBytes(filePath, response.getOutputStream());if (delete){FileUtils.deleteFile(filePath);}}catch (Exception e){log.error("下载文件失败", e);}}/*** 通用上传请求*/@PostMapping("/common/upload")public AjaxResult uploadFile(MultipartFile file) throws Exception{try{// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称String fileName = FileUploadUtils.upload(filePath, file);String url = serverConfig.getUrl() + fileName;AjaxResult ajax = AjaxResult.success();ajax.put("fileName", fileName);ajax.put("url", url);return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}}/*** 通用上传请求返回磁盘路径*/@PostMapping("/common/uploadWithAbsolutePath")public AjaxResult uploadFileWithAbsolutePath(MultipartFile file) throws Exception{try{// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称String fileName = FileUploadUtils.uploadWithAbsolutePath(filePath, file);AjaxResult ajax = AjaxResult.success();ajax.put("uploadpath", filePath+ File.separator+fileName);return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}}/*** 本地资源通用下载*/@GetMapping("/common/download/resource")public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)throws Exception{try{if (!FileUtils.checkAllowDownload(resource)){throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));}// 本地资源路径String localPath = RuoYiConfig.getProfile();// 数据库资源地址String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);// 下载名称String downloadName = StringUtils.substringAfterLast(downloadPath, "/");response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, downloadName);FileUtils.writeBytes(downloadPath, response.getOutputStream());}catch (Exception e){log.error("下载文件失败", e);}}/*** 本地资源通用下载*/@GetMapping("/common/download/resourceeasy")public void resourceDownloadEasy(String resource, HttpServletRequest request, HttpServletResponse response)throws Exception{try{if (!FileUtils.checkAllowDownload(resource)){throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));}response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, resource);FileUtils.writeBytes(resource, response.getOutputStream());}catch (Exception e){log.error("下载文件失败", e);}}
}

SpringBoot+Vue+OpenOffice实现文档管理(文档上传、下载、在线预览)相关推荐

  1. 用openoffice+jodconverter+webuploader+pdf.js实现文件上传、在线预览功能

    一.背景 最近公司一个项目要实现一个文件上传以及多文档在线预览的功能,之前一直做无线工具开发的,没有涉及到这些东西.另外项目组缺java开发人员,而且自己也只是一个半吊子前端加小半吊子java开发人员 ...

  2. JSP实现word文档的上传,在线预览,下载

    前两天帮同学实现在线预览word文档中的内容,而且需要提供可以下载的链接!在网上找了好久,都没有什么可行的方法,只得用最笨的方法来实现了.希望得到各位大神的指教.下面我就具体谈谈自己的实现过程,总结一 ...

  3. java word上传下载_JSP实现word文档的上传,在线预览,下载

    前两天帮同学实现在线预览word文档中的内容,而且需要提供可以下载的链接!在网上找了好久,都没有什么可行的方法,只得用最笨的方法来实现了.希望得到各位大神的指教.下面我就具体谈谈自己的实现过程,总结一 ...

  4. SpringBoot实现PPT格式文件上传并在线预览

    1.需要引入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf< ...

  5. Java通过openOffice实现word,excel,ppt转成pdf实现在线预览

    Java通过openOffice实现word,excel,ppt转成pdf实现在线预览 一.OpenOffice 1.1 下载地址 1.2 JodConverter 1.3 新建实体类PDFDemo ...

  6. 前后端分离跨服务器文件上传,SpringBoot+Vue.js实现前后端分离的文件上传功能

    这篇文章需要一定vue和springboot的知识,分为两个项目,一个是前端vue项目,一个是后端springboot项目. 后端项目搭建 我使用的是springboot1.5.10+jdk8+ide ...

  7. 使用Vue+go实现前后端文件的上传下载,csv文件上传下载可直接照搬

    直接上代码,就是固定用法,只需改动接口等一些信息就可以.这里顺带也把token带过去了, vue前端 //页面代码,使用的是vue ant,每个框架都可以实现,详情请看自己使用框架的wiki<a ...

  8. JAVA-文件文档在线预览项目解决方案-kkFileView

    1. 简介 kkFileView是文件文档在线预览项目解决方案,对标业务付费产品有 永中office,office365,idocv等.该项目使用六星的springboot大家,易上手和部署,基本支持 ...

  9. 前端页面预览word_前端实现在线预览文档

    前端实现在线预览文档 发布时间:2019-06-03 17:22, 浏览次数:529 <>前端实现在线预览文档 最近项目开发中需要实现在线预览Word,Excel,PowerPoint格式 ...

  10. 前端实现在线预览文档

    前端实现在线预览文档 最近项目开发中需要实现在线预览Word,Excel,PowerPoint格式的文档,网上查找了很多资源,各说纷纭,但是在一一尝试之后只有使用微软的预览接口才能成功,其他的会出现各 ...

最新文章

  1. 2014年下半年信息系统项目管理师上午试题试题与答案 54
  2. Servlet-监听器(ServletContext、Request、Session)
  3. 计算机一级汉字录入在线联系,计算机一级考试指导:汉字录入题的操作
  4. Android TextView 高亮字体并添加点击事件
  5. nginx的启动、停止、平滑重启
  6. document.all和document.layers
  7. tensorflow 转张量类型为float_5个简单的步骤掌握Tensorflow的Tensor
  8. 多线程有几种实现方法?同步有几种实现方法?
  9. 服务注册中心---服务发现nacos
  10. 使用HTML制作简易求职表
  11. python saveas_如何使用Python SaveAs对话框
  12. 摄像头录像存储计算方式
  13. 人工智能写歌词?看我是如何用Python来C位出道的……
  14. discuz 论坛配置 QQ/163 网易邮箱
  15. UE5 c++ 写一个livelink插件
  16. 辅助功能 AccessibilityService笔记
  17. 【ChatGPT调教】调教ChatGPT案例
  18. 利用callKit实现电话防骚扰
  19. 电脑文件删不掉怎么办?数据误删也能恢复
  20. Nginx + ModSecurity 报错

热门文章

  1. 程序的格式框架语法元素的名称(Python)
  2. Python---Pickle模块
  3. JavaScript的常用工具汇总
  4. Java的多线程和线程池的使用,你真的清楚了吗?
  5. 在java中读取某个文件中的数据内容
  6. android 坐标图绘制曲线,Android艺术之画一条平滑的曲线
  7. 太原理工软件学院c语言2020,太原理工软件工程C语言实验报告 数组.doc
  8. mysql 归档日志恢复_Oracle丢失归档日志文件的数据库恢复方法
  9. mplus 软件_Mplus 8.3 Combo Version 多元统计分析软件(Win)
  10. 简述sqlite数据库的特点_为什么要用SQLITE?SQLITE数据库优点和缺点分析