kindeditor官网:http://kindeditor.net/demo.php

  kindeditor在之前已经用过,现在在springboot项目中使用。并且也在里面使用了图片上传以及回显等功能。

  其实主要的功能是图片的处理:kindeditor对输入的内容会作为html标签处理,对于image的做法是先将图片传到后台服务器,然后上传成功之后回传图片的URL,之后内容中增加springboot中使用kindeditor富文本编辑器实现博客功能&vue-elementui使用vue-kindeditor  第1张进行回显,当然保存到数据库也是img标签进行保存的。对于文件上传是以a标签的形式进行回显,数据库也以a标签进行保存。

  下面的代码涉及到了:Restful风格的请求、SpringMVC文件的上传、不配置虚拟路径的前提下请求图片资源、kindeditor、thymeleaf模板的使用。

1.首先编写接收kindeditor图片上传和图片请求的类:

package cn.qs.controller.common;

import java.io.File;

import java.io.FileInputStream;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;

import org.apache.commons.io.IOUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.multipart.MultipartFile;

import cn.qs.bean.common.Document;

import cn.qs.service.common.DocumentService;

import cn.qs.utils.UUIDUtils;

import cn.qs.utils.file.FileHandleUtil;

import cn.qs.utils.file.TikaUtils;

import cn.qs.utils.system.MySystemUtils;

@Controller

@RequestMapping("document")

public class DocumentController {

private static final Logger logger = LoggerFactory.getLogger(DocumentController.class);

@Autowired

private DocumentService documentService;

/**

* Restful风格获取文档

*

* @param request

* @param response

* @param documentId

*/

@RequestMapping("/getDocument/{documentId}")

public void getPicture(HttpServletRequest request, HttpServletResponse response,

@PathVariable() String documentId) {

FileInputStream in = null;

ServletOutputStream outputStream = null;

try {

Document document = documentService.getById(documentId);

String path = document.getPath();

String originName = document.getOriginName();

File fileByName = FileHandleUtil.getFileByName(path);

// 判断文件类型,image、pdf返回阅读,其他下载

String fileType = TikaUtils.getFileType(fileByName);

if (!TikaUtils.TYPE_IMAGE.equals(fileType) && !TikaUtils.TYPE_PDF.equals(fileType)) {

response.setContentType("application/force-download");

response.setHeader("Content-Disposition", "attachment;fileName=" + originName);

}

in = new FileInputStream(fileByName);

outputStream = response.getOutputStream();

IOUtils.copyLarge(in, outputStream);

} catch (Exception e) {

e.printStackTrace();

} finally {

IOUtils.closeQuietly(in);

IOUtils.closeQuietly(outputStream);

}

}

/**

* 文档上传

*

* @param imgFile

* @return

*/

@RequestMapping("/upload")

@ResponseBody

public Map uploadPicture(MultipartFile imgFile) {

Map result = new HashMap();

result.put("error", 1);

if (imgFile == null) {

result.put("message", "文件没接到");

return result;

}

logger.debug("file -> {},viewId ->{}", imgFile.getOriginalFilename());

String fileOriName = imgFile.getOriginalFilename();// 获取原名称

String fileNowName = UUIDUtils.getUUID2() + "." + FilenameUtils.getExtension(fileOriName);// 生成唯一的名字

try {

FileHandleUtil.uploadSpringMVCFile(imgFile, fileNowName);

} catch (Exception e) {

logger.error("uploadPicture error", e);

return result;

}

String id = UUIDUtils.getUUID();

Document document = new Document();

document.setCreatetime(new Date());

document.setPath(fileNowName);

document.setId(id);

document.setOriginName(fileOriName);

document.setUploaderUsername(MySystemUtils.getLoginUsername());

documentService.insert(document);

// 回传JSON结果

result.put("error", 0);

result.put("url", "/document/getDocument/" + id);

return result;

}

  图片上传:参数接受名字必须是imgFile,否则接收不到文件。收到文件之后先生成一个全局唯一的名称然后保存到本地,并保存到数据库之后返回一个图片的URL例如:  /document/getDocument/94995b51-901c-44e9-87ec-12c109098f5e

  图片获取:通过restful风格的请求将图片的ID传到后台,根据ID查询到图片的路径,然后调用IOUtils将文件流回传回去实现图片的src请求显示。如果是其他类型的文件以下载的方式进行回传流。

 

Document实体类如下:

package cn.qs.bean.common;

import java.util.Date;

import javax.persistence.Entity;

import javax.persistence.Id;

//系统文档表

@Entity

public class Document {

@Id

private String id;

/**

* 原名字

*/

private String originName;

/**

* 上传者

*/

private String uploaderUsername;

private String name;

private String path;

private Date createtime;

private String remark1;

private String remark2;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name == null ? null : name.trim();

}

public String getPath() {

return path;

}

public void setPath(String path) {

this.path = path == null ? null : path.trim();

}

public Date getCreatetime() {

return createtime;

}

public void setCreatetime(Date createtime) {

this.createtime = createtime;

}

public String getRemark1() {

return remark1;

}

public void setRemark1(String remark1) {

this.remark1 = remark1;

}

public String getRemark2() {

return remark2;

}

public void setRemark2(String remark2) {

this.remark2 = remark2;

}

public String getOriginName() {

return originName;

}

public void setOriginName(String originName) {

this.originName = originName;

}

public String getUploaderUsername() {

return uploaderUsername;

}

public void setUploaderUsername(String uploaderUsername) {

this.uploaderUsername = uploaderUsername;

}

}

 

 

FileHandleUtil类是图片保存以及获取,保存到本地的固定文件夹下面。

package cn.qs.utils;

import java.io.File;

import java.util.Locale;

import java.util.ResourceBundle;

import org.apache.commons.io.FileUtils;

import org.apache.commons.lang3.StringUtils;

import org.springframework.web.multipart.MultipartFile;

public class FileHandleUtil {

public static final String LANGUAGE = "zh";

public static final String COUNTRY = "CN";

private static String getProperties(String baseName, String section) {

String retValue = "";

try {

Locale locale = new Locale(LANGUAGE, COUNTRY);

ResourceBundle rb = ResourceBundle.getBundle(baseName, locale);

retValue = (String) rb.getObject(section);

} catch (Exception e) {

}

return retValue;

}

public static String getValue(String fileName, String key) {

String value = getProperties(fileName, key);

return value;

}

public static boolean deletePlainFile(String propertiesFileName, String fileName) {

if (fileName == null) {

return false;

}

String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/");

try {

FileUtils.deleteQuietly(new File(fileDir + fileName));

} catch (Exception e) {

return false;

}

return true;

}

public static boolean uploadSpringMVCFile(MultipartFile multipartFile, String fileName) throws Exception {

String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/");

if (!new File(fileDir).exists()) {

new File(fileDir).mkdirs();

}

multipartFile.transferTo(new File(fileDir + fileName));// 保存文件

return true;

}

public static File getFileByName(String path) {

String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/");

return new File(fileDir+path);

}

}

 

TikaUtils是提取文件类型的工具类,依赖的jar包如下:

org.apache.tika

tika-parsers

1.17

工具类源码如下:

package cn.qs.utils.file;

import java.io.File;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;

import org.apache.tika.Tika;

public class TikaUtils {

// 总的文件类型分为下面几类

public static final String TYPE_OFFICE = "OFFICE";

public static final String TYPE_PDF = "PDF";

public static final String TYPE_IMAGE = "IMAGE";

public static final String TYPE_VIDEO = "VIDEO";

public static final String TYPE_OTHER = "OTHER";

// tika解析的文件信息

private static final String WORD_DOC = "application/msword";

private static final String WORD_PPT = "application/vnd.ms-powerpoint";

private static final String WORD_EXCEL = "application/vnd.ms-excel";

private static final String WORD_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";

private static final String WORD_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation";

private static final String WORD_EXCELX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

private static final String VIDEO = "video/";

private static final String IMAGE = "image/";

private static final String TEXT = "text/plain";

private static final String CSS = "text/css";

private static final String HTML = "text/html";

private static final String PDF = "application/pdf";

private static final String ZIP = "application/zip";

private static final String RAR = "application/x-rar-compressed";

public static String getFileType(File file) {

if (file == null || !file.exists()) {

return "";

}

Tika tika = new Tika();

String filetype = null;

try {

filetype = tika.detect(file);

} catch (IOException ignore) {

// ignore

return "error";

}

if (StringUtils.isBlank(filetype)) {

return "error";

}

if (WORD_DOC.equals(filetype) || WORD_PPT.equals(filetype) || WORD_EXCEL.equals(filetype)

|| WORD_DOCX.equals(filetype) || WORD_PPTX.equals(filetype) || WORD_EXCELX.equals(filetype)) {

return TYPE_OFFICE;

}

if (filetype.startsWith(VIDEO)) {

return TYPE_VIDEO;

}

if (filetype.startsWith(IMAGE)) {

return TYPE_IMAGE;

}

if (filetype.equals(PDF)) {

return TYPE_PDF;

}

return TYPE_OTHER;

}

}

 

2.前台界面准备富文本编辑器并且保存输入的信息到数据库

欢迎页面-X-admin2.0

*博客标题

autocomplete="off" class="layui-input"/>

*内容

界面如下:

 

最终生成的内容保存到数据库之后如下:

        测试

springboot中使用kindeditor富文本编辑器实现博客功能&vue-elementui使用vue-kindeditor  第2张

springboot中使用kindeditor富文本编辑器实现博客功能&vue-elementui使用vue-kindeditor  第3张

 

最终经过代码处理后在界面显示如下:

@RequestMapping("/getBlogdetail/{blogId}")

public String getBlogdetail(ModelMap map, @PathVariable() Integer blogId, HttpServletRequest request) {

Blog blog = blogService.getBlogdetail(blogId);

// 获取当前用户

HttpSession session = request.getSession();

User user = (User) session.getAttribute("user");

String username = user.getUsername();

String blogUsername = StringUtils.defaultIfBlank(blog.getBlogblank(), "admin");

if (blogUsername.equals(username)) {

map.put("blog", blog);

} else {

map.put("blog", new Blog());

}

return "blogDetail";

}

 


 

 

补充:kindeditor可选的显示插件有好多,如下需要的时候items里面增加对应的选项即可

items : [

'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',

'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',

'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',

'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',

'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',

'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',

'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',

'anchor', 'link', 'unlink', '|', 'about'

]

 

源码git地址:https://github.com/qiao-zhi/bs-tourism2.git

 

3.前后端分离项目vue-elementui中使用kindeditor

git地址: https://github.com/ff755/vue-kindeditor

大致安装步骤如下:

0.设置淘宝镜像:

npm config set registry https://registry.npm.taobao.org

npm config get registry

(如果上面配置正确,会显示https://registry.npm.taobao.org )

1. 添加vue-kindedtior

在终端项目目录下执行

npm install vue-kindeditor --save-dev

2.使用vue-kindedtior

第一步,编辑 demo/src/main.js 文件

import Vue from 'vue'

import App from './App'

// 引入 vue-kikindeditor 需要的文件

import VueKindEditor from 'vue-kindeditor'

import 'kindeditor/kindeditor-all-min.js'

import 'kindeditor/themes/default/default.css'

Vue.config.productionTip = false

// 注册 vue-kikindeditor plugin

Vue.use(VueKindEditor)

/* eslint-disable no-new */

new Vue({

el: '#app',

template: '',

components: { App }

})

编辑完配置文件后,就可以在组件中使用了。

第二步,编辑 demo/src/components/Hello.vue 文件

在 Hello.vue 中添加如下代码

返回浏览器就可以看到编辑器了。

使用 editor 标签使用kindeditor。

参数:

id: 设置编辑器的id,kindeditor创建使用需要用到,所以必填。例子:editor_id

content: 用来获取编辑器内容,使用双向绑定获取编辑器内容数据。例子:editorText

loadStyleMode: 是否自动加载kindeditor需要的css文件,默认是从 / 查找,所以设置为false,搭配pluginsPath使用

pluginsPath: 设置编辑器的plugins目录。例子中为了方便把kindeditor全部目录复制到了demo/static中了,实际使用中地址自行设置。

3.关于图片上传:(使用该编辑器我主要是使用图片上传)

vue.config.js使用的是proxy,代理如下:

proxy: {

'/api': {

target: 'http://localhost:8088',

ws: true,

changeOrigin: true,

pathRewrite: {

'^/api': ''

}

}

}

 

后台代码只需要修改返回的地址加上/api 以供前端代理请求,如下:

/**

* 文档上传

*

* @param imgFile

* @return

*/

@RequestMapping("/upload")

@ResponseBody

public Map uploadPicture(MultipartFile imgFile) {

Map result = new HashMap();

result.put("error", 1);

if (imgFile == null) {

result.put("message", "文件没接到");

return result;

}

logger.debug("file -> {},viewId ->{}", imgFile.getOriginalFilename());

String fileOriName = imgFile.getOriginalFilename();// 获取原名称

String fileNowName = UUIDUtils.getUUID2() + "." + FilenameUtils.getExtension(fileOriName);// 生成唯一的名字

try {

FileHandleUtil.uploadSpringMVCFile(imgFile, fileNowName);

} catch (Exception e) {

logger.error("uploadPicture error", e);

return result;

}

String id = UUIDUtils.getUUID();

Document document = new Document();

document.setCreatetime(new Date());

document.setPath(fileNowName);

document.setId(id);

document.setOriginName(fileOriName);

document.setUploaderUsername(MySystemUtils.getLoginUsername());

documentService.insert(document);

// 回传JSON结果

result.put("error", 0);

result.put("url", "/api/document/getDocument/" + id);

return result;

}

 

editor修改为如下:

pluginsPath="/static/kindeditor/plugins/"

:loadStyleMode="false"

uploadJson="/api/blogPicture/uploadPicture.html"

filePostName="imgFile"

@on-content-change="onContentChange">

 

4.实现文件上传

  kindeditor实现更多的插件,文件上传和图片上传也可以单独的使用,不在textarea里面使用。

  有时候需要实现文件上传,文件上传和图片上传的思路是一样的。

我们用到的controller还是上面的controller,只是在items增加文件上传选项。  allowFileUpload: true 表示允许上传本地文件、items中增加'insertfile' 表示显示菜单。

显示:

 

  文件上传之后相当于editor给我们增加了一个a标签,href属性为我们返回的url,a标签的text为说明,如下:

   我们点击的时候会用a标签访问我们的URL,当浏览器可以解析的文件时会显示,不解析的会以下载的形式进行下载。

 

  这个文件上传成功之后会alert(上传成功),有时候体验不是很好。通过查看源码发现在kindeditor\plugins\insertfile目录的insertfile.js文件的87行左右,如果不想 打印我们去掉打印效果即可,当然也可以自己修改上传成功的源码,如下:

 

   如果我们希望文件在线预览,可以修改后台代码,在调用URL获取文件信息的时候转为PDF返回到流中。当然可以结合kkFileView(git上一个在线预览,也是基于libreoffice转换pdf进行预览,只不过封装了界面与更多的文件类型判断)

 

补充:vue-kindeditor中修改文件上传后的代码

  这里涉及到了修改node_modules文件夹下面的文件,比如我们需要修改:node_modules\kindeditor\plugins\insertfile\insertfile.js

(1)安装patch-package

npm i patch-package --save-dev

(2)修改模块中文件:

(3)执行如下命令(kindeditor是在node_modules下面的文件夹名称)

npx patch-package kindeditor

(4)执行完成会在项目的根路径生成一个patches文件夹,下面的文件记录了差异

 文件内容如下:

diff --git a/node_modules/kindeditor/plugins/insertfile/insertfile.js b/node_modules/kindeditor/plugins/insertfile/insertfile.js

index 0a4ce9e..6725451 100644

--- a/node_modules/kindeditor/plugins/insertfile/insertfile.js

+++ b/node_modules/kindeditor/plugins/insertfile/insertfile.js

@@ -84,7 +84,7 @@ KindEditor.plugin('insertfile', function(K) {

if (self.afterUpload) {

self.afterUpload.call(self, url, data, name);

}

- alert(self.lang('uploadSuccess'));

+ // alert(self.lang('uploadSuccess'));

} else {

alert(data.message);

}

(5)修改package.json,scripts加入:

"postinstall": "patch-package"

 

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。