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


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

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

      其实主要的功能是图片的处理:kindeditor对输入的内容会作为html标签处理,对于image的做法是先将图片传到后台服务器,然后上传成功之后回传图片的URL,之后内容中增加<img src='url'>进行回显,当然保存到数据库也是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<String, Object> uploadPicture(MultipartFile imgFile) {
            Map<String, Object> result = new HashMap<String, Object>();
            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包如下:

            <!--tika解析文本内容 -->
            <dependency>
                <groupId>org.apache.tika</groupId>
                <artifactId>tika-parsers</artifactId>
                <version>1.17</version>
            </dependency>

    工具类源码如下:

    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.前台界面准备富文本编辑器并且保存输入的信息到数据库

    <!DOCTYPE html>
    <html>
      
      <head>
        <meta charset="UTF-8"/>
        <title>欢迎页面-X-admin2.0</title>
        <meta name="renderer" content="webkit"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
        <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/font.css'}"/>
        <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/xadmin.css'}"/>
        <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/js/jquery.min.js'}" charset="utf-8"></script>
        <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/lib/layui/layui.js'}" charset="utf-8"></script>
        <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/js/xadmin.js'}"></script>
        
        <!-- kindeditor相关  -->
           <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/kindeditor/themes/default/default.css'}" />
           <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/kindeditor/plugins/code/prettify.css'}" />
        <script charset="utf-8" th:src="${#httpServletRequest.getContextPath()+'/static/kindeditor/kindeditor-all.js'}"></script>
        <script charset="utf-8" th:src="${#httpServletRequest.getContextPath()+'/static/kindeditor/lang/zh-CN.js'}"></script>
           <script>
        var editor;
        KindEditor.ready(function(K) {
            editor = K.create('textarea[name="contentEditor"]', {
                resizeType : 1,
                allowPreviewEmoticons : false,
                uploadJson : '/document/upload.html',
                allowImageUpload : true,
                pasteType : 0,      //设置能否粘贴
                items : [
                    'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline',
                    'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
                    'insertunorderedlist', '|', 'emoticons', 'image', 'link','fullscreen']
            });
        });
        </script>
        
        <!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
        <!--[if lt IE 9]>
          <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
          <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
      </head>
      
      <body>
        <div class="x-body layui-anim layui-anim-up">
        
         <form class="layui-form">
              <div class="layui-form-item">
                  <label for="L_email" class="layui-form-label">
                      <span class="x-red">*</span>博客标题
                  </label>
                  <div class="layui-input-inline">
                      <input type="text" id="L_blogtitle" name="blogtitle" lay-verify="required"
                      autocomplete="off" class="layui-input"/>
                  </div>
              </div>
              <div class="layui-form-item">
                  <label for="L_email" class="layui-form-label">
                      <span class="x-red">*</span>内容
                  </label>
                  <div class="layui-input-inline">
                      <textarea name="contentEditor" id="test" cols="100" rows="8" style="700px;height:200px;visibility:hidden;"></textarea>
                  </div>
              </div>
               
              <div class="layui-form-item">
                  <label for="L_repass" class="layui-form-label">
                  </label>
                  <button  class="layui-btn" lay-filter="add" lay-submit="">
                      增加
                  </button>
              </div>
          </form>
        </div>
      </body>
          <script>
          /*<![CDATA[*/
            layui.use(['form','layer'], function(){
               $ = layui.jquery;
              var form = layui.form
              ,layer = layui.layer;
            
              //监听提交
              form.on('submit(add)', function(data){
                  var data = {
                         "blogtitle":$('[name="blogtitle"]').val(),
                         "content":editor.html()
                  }
                   //异步提交数据
                     $.post("/blog/doAddBlog.html",data,function(response){
                       if(response.success == true){
                         layer.msg("增加成功", {icon: 6},function () {
                          // 获得frame索引
                          var index = parent.layer.getFrameIndex(window.name);
                          //关闭当前frame
                          parent.layer.close(index);
                          // 父页面刷新
                          parent.location.reload();
                      });
                       }else{
                           layer.alert(response.msg);
                       }
                   }); 
                return false;
              });
            });
            /*]]>*/
        </script>
    
    </html>

    界面如下:

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

    <p>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;测试
    </p>
    <p>
        <img src="http://localhost:8088/static/kindeditor/plugins/emoticons/images/20.gif" border="0" alt="" />
    </p>
    <p>
        <img src="/document/getDocument/efe5134f-8a41-4e75-9108-6ab045979db6" alt="" />
    </p>

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

        @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";
        }
    <!DOCTYPE html>
    <html>
      
      <head>
        <meta charset="UTF-8"/>
        <title th:text="${blog.blogtitle}"></title>
        <meta name="renderer" content="webkit"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
        <link rel="shortcut icon" href="/static/x-admin/favicon.ico" type="image/x-icon" />
        <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/font.css'}"/>
        <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/xadmin.css'}"/>
        <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
        <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/lib/layui/layui.all.js'}" charset="utf-8"></script>
        <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/js/xadmin.js'}"></script>
        
        <span th:if="${session.user.username} eq 'admin'">
            <script>
                var admin = true;
            </script>
        </span>
        <style type="text/css">
        body{ 
        text-align:center;
        background-color: #dcdcdc;
        }
        #container{
            text-align:left;
            margin:0 auto;
            width: 80%;
            background-color: #fff;
        }
        </style>
      </head>
      
      <body class="layui-anim layui-anim-up">
          <div id="container">
                <center>
                  <h1 th:text="${'标题:'+blog.blogtitle}"></h1>
                  <h2 th:text="${'所属人'+blog.blogblank}"></h2>
              </center>
                <hr/>
                <span th:utext="${blog.content}"></span>
          </div>
      </body>
    </html>

    补充: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: '<App/>',
      components: { App }
    })

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

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

    在 Hello.vue 中添加如下代码

    <template>
      <div class="hello">
         <editor id="editor_id" height="500px" width="700px" :content="editorText"
            pluginsPath="/static/kindeditor/plugins/"
            :loadStyleMode="false"
            @on-content-change="onContentChange"></editor>
      </div>
    </template>
    
    <script>
    export default {
      name: 'hello',
      data () {
        return {
           editorText: ''
        }
      }, 
      methods: {
        onContentChange (val) {
          this.editorText = val
        }
      }
    }
    </script>

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

    使用 editor 标签使用kindeditor。<editor  ...></editor>
    参数:   
    
        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<String, Object> uploadPicture(MultipartFile imgFile) {
            Map<String, Object> result = new HashMap<String, Object>();
            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修改为如下:

             <editor id="editor_id" height="200px" width="200px" :content="addForm.content"
                pluginsPath="/static/kindeditor/plugins/"
                :loadStyleMode="false" 
                uploadJson="/api/blogPicture/uploadPicture.html"
                filePostName="imgFile"
                @on-content-change="onContentChange"></editor>
           </el-form-item>

    4.实现文件上传

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

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

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

           <script>
        var editor;
        KindEditor.ready(function(K) {
            editor = K.create('textarea[name="contentEditor"]', {
                resizeType : 1,
                allowPreviewEmoticons : false,
                uploadJson : '/document/upload.html',
                allowImageUpload : true,
                allowFileUpload: true,
                pasteType : 0,      //设置能否粘贴
                items : [
                    'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline',
                    'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
                    'insertunorderedlist', '|', 'emoticons', 'image', "insertfile", 'link','fullscreen']
            });
        });
        </script>

    显示:

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

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

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

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

  • 相关阅读:
    常用的16个Java实用工具类,Java开发人员请收藏!
    JVM内存区域与垃圾回收
    听说你还不知道Java代码是怎么运行的?
    Java 到底是值传递还是引用传递?
    Java线程池实现原理及其在美团业务中的实践
    别再说Java对象都是在堆内存上分配空间的了!
    面试常问的Java虚拟机内存模型,看这篇就够了!
    好用的Java工具类库,GitHub星标10k+你在用吗?
    MySQL 全文索引实现一个简单版搜索引擎
    laravel 数据库里的图片重命名
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10685460.html
Copyright © 2020-2023  润新知