springboot使用quill富文本编辑器的插件,自定义图片上传,自定义视频上传

1.问题描述:

  1. quill自带的图片上传是base64,直接存入数据库的话,在多图片时可能会有溢出风险。所以改用ajax发送formData自定义图片上传

2.原理流程

通过自定义一个input上传图片,在onchagne时发送ajax请求,后台写入之后返回url到前端,插入显示

3.自定义图片上传具体代码

要注意quill的版本,有些人就是版本不对然后效果出不来,可以去quill官网找最新的cdn链接https://quilljs.com/

前端代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>Quill</title>
    <link href="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.snow.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.bubble.css" rel="stylesheet">
    <style>
        body {
            padding: 10px 30px;
        }
        #editor {
            min-height: 180px;
        }
    </style>
</head>
<body>
<div>jjsjsj</div>
<!--存放富文本div-->
<div id="editor" class="showContent">
    <!--回显的内容-->
    <!--可以直接在指定元素内加入文本或者html标签-->
</div>
<!-- 单图片上传:this.files[0] 图片列表的第0项,也就是当前选择的图片 -->
<input type="file" onchange="updateImg(this.files[0])" id="imgData" style="display: none;">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="//cdn.quilljs.com/1.3.6/quill.js"></script>
<script src="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.js"></script>
<script>
    var quill;
    $(function() {
        /* 编辑器操作条选项 */
        var toolbarOptions = [
            ['bold', 'italic', 'underline', 'strike'], //加粗、倾斜、下划线、删除线
            [{'align': []}], //内容对齐方式:左对齐、右对齐、居中、平行
            [{'color': []}, {'background': []}], //字体颜色、文本的背景色
            ['image'],  //图片上传
            ['clean'], //清除格式
            [{'header': 1}, {'header': 2}], //标题H1 H2
            [{'list': 'ordered'}, {'list': 'bullet'}],  //数据列表
            [{'script': 'sub'}, {'script': 'super'}],   // 上标、下标
            [{'indent': '-1'}, {'indent': '+1'}],   // 缩进、减少缩进
            [{'size': ['small', false, 'large', 'huge']}], // 自定义下拉:字体的样式....跟加粗差不多
            [{'header': [1, 2, 3, 4, 5, 6, false]}],  //标题 H1 H2 H3......
            [{'direction': 'rtl'}], // 文本方向
            [{'font': []}],
            ['blockquote', 'code-block']
            // ['video'], //视频上传
            // ['formula'] //需要加载cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js
        ];
        /**
         * 初始化富文本,绑定一个div: div id为editor
         */
        quill = new Quill('#editor', {
            modules: {
                toolbar: toolbarOptions  //指定编辑器操作条
            },
            theme: 'snow', //主题,有两种,snow和bubble,一般都是使用snow
            placeholder: '请输入内容....',
            readOnly: false
        });
        
        //修改样式
        var Align = Quill.import('attributors/style/align');
        Align.whitelist = ['right', 'center', 'justify'];
        Quill.register(Align, true);
        /* 传入布尔值,控制编辑器是否可用 */
        quill.enable();
        //quill.blur(); //失去焦点
        //quill.focus(); //获得焦点

        /**
         * 自定义上传图片第二步
         *
         * 通过addHander监听点击控件事件:image事件
         */
        var toolbar = quill.getModule('toolbar');
        toolbar.addHandler('image',function () {
            $('#imgData').click();
        });
    });

    /**
     * 自定义上传图片第三步
     *
     * 图片上传接口
     */
    function updateImg(file) {
        var formData = new FormData();
        formData.append('file', file);
        $.ajax({
            url: '/uploadPhoto',                        //url
            type: 'post',                        //以post发送
            data: formData,             //要发送的数据。后端接收$_POST['user']
            dataType: 'json',                  //返回的数据类型
            cache: false,
            traditional: true,
            contentType: false,
            processData: false,
            success: function (res) {
                /*console.log(res);*/
                //图片上传成功之后的回调
                const range = quill.getSelection();
                if (range) {
                    //将上传好的图片,插入到富文本的range.index(当前光标处)
                    quill.insertEmbed(range.index, 'image', "" + res.src);
                }
            },
            error: function (e) {
                console.log(e);
            }
        });
    }

    /**
     * 获取富文本内容方法(提交)
     */
    function submitData() {
        res = quill.container.firstChild.innerHTML; //获取当前富文本编辑器实例的内容(带html标签)
        console.log(res); //获取当前富文本编辑器实例的内容(带html标签)
    };
</script>
</body>
</html>

后端代码,使用java,下面展示上传图片的controller

@RequestMapping("/uploadPhoto")
    @ResponseBody
    public Map<String,String> testQuestion(@RequestParam MultipartFile file){
        Map<String,String> data = new HashMap<>();
       OutputStream os = null;
            InputStream inputStream = null;
            String fileName = System.currentTimeMillis() + ".jpg";
            String userUrl = savePath+fileName;
            try {
                inputStream = photo.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                byte[] bs = new byte[1024];
                int len;
                // 输出的文件流保存到本地文件
                File tempFile = new File(writePath);
                if (!tempFile.exists()) {
                    tempFile.mkdirs();
                }
                os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
                // 开始读取
                while ((len = inputStream.read(bs)) != -1) {
                    os.write(bs, 0, len);
                }
                os.flush();
        data.put("src", userUrl);
        return data;
    }

在这里插入图片描述

4.自定义视频上传

其实自定义上传视频和上传图片是一个样的,原理都是写入文件后,回传url
前端

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>Quill</title>
    <link href="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.snow.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.bubble.css" rel="stylesheet">
    <style>
        body {
            padding: 10px 30px;
        }
        #editor {
            min-height: 180px;
        }
    </style>
</head>
<body>
<div>jjsjsj</div>
<!--存放富文本div-->
<div id="editor" class="showContent">
    <!--回显的内容-->
    <!--可以直接在指定元素内加入文本或者html标签-->
</div>
<!-- 单图片上传:this.files[0] 图片列表的第0项,也就是当前选择的图片 -->
<input type="file" onchange="updateImg(this.files[0])" id="imgData" style="display: none;">

<!--用来上传图片的input-->
<input type="file" onchange="uploadVideo(this.files[0])" id="uploadVideo" style="display:none" >

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="//cdn.quilljs.com/1.3.6/quill.js"></script>
<script src="https://cdn.bootcss.com/quill/2.0.0-dev.3/quill.js"></script>
<script>
    var quill;
    $(function() {
        /* 编辑器操作条选项 */
        var toolbarOptions = [
            ['bold', 'italic', 'underline', 'strike'], //加粗、倾斜、下划线、删除线
            [{'align': []}], //内容对齐方式:左对齐、右对齐、居中、平行
            [{'color': []}, {'background': []}], //字体颜色、文本的背景色
            ['image'],  //图片上传
            ['clean'], //清除格式
            [{'header': 1}, {'header': 2}], //标题H1 H2
            [{'list': 'ordered'}, {'list': 'bullet'}],  //数据列表
            [{'script': 'sub'}, {'script': 'super'}],   // 上标、下标
            [{'indent': '-1'}, {'indent': '+1'}],   // 缩进、减少缩进
            [{'size': ['small', false, 'large', 'huge']}], // 自定义下拉:字体的样式....跟加粗差不多
            [{'header': [1, 2, 3, 4, 5, 6, false]}],  //标题 H1 H2 H3......
            [{'direction': 'rtl'}], // 文本方向
            [{'font': []}],
            ['blockquote', 'code-block']
            ['video'], //视频上传
            // ['formula'] //需要加载cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js
        ];
        /**
         * 初始化富文本,绑定一个div: div id为editor
         */
        quill = new Quill('#editor', {
            modules: {
                toolbar: toolbarOptions  //指定编辑器操作条
            },
            theme: 'snow', //主题,有两种,snow和bubble,一般都是使用snow
            placeholder: '请输入内容....',
            readOnly: false
        });
        
        //修改样式
        var Align = Quill.import('attributors/style/align');
        Align.whitelist = ['right', 'center', 'justify'];
        Quill.register(Align, true);
        /* 传入布尔值,控制编辑器是否可用 */
        quill.enable();
        //quill.blur(); //失去焦点
        //quill.focus(); //获得焦点

        /**
         * 自定义上传图片第二步
         *
         * 通过addHander监听点击控件事件:image事件
         */
        var toolbar = quill.getModule('toolbar');
        toolbar.addHandler('image',function () {
            $('#imgData').click();
        });
    });

    /**
     * 自定义上传图片第三步
     *
     * 图片上传接口
     */
    function updateImg(file) {
        var formData = new FormData();
        formData.append('file', file);
        $.ajax({
            url: '/uploadPhoto',                        //url
            type: 'post',                        //以post发送
            data: formData,             //要发送的数据。后端接收$_POST['user']
            dataType: 'json',                  //返回的数据类型
            cache: false,
            traditional: true,
            contentType: false,
            processData: false,
            success: function (res) {
                /*console.log(res);*/
                //图片上传成功之后的回调
                const range = quill.getSelection();
                if (range) {
                    //将上传好的图片,插入到富文本的range.index(当前光标处)
                    quill.insertEmbed(range.index, 'image', "" + res.src);
                }
            },
            error: function (e) {
                console.log(e);
            }
        });
    }

    /**
     * 获取富文本内容方法(提交)
     */
    function submitData() {
        res = quill.container.firstChild.innerHTML; //获取当前富文本编辑器实例的内容(带html标签)
        console.log(res); //获取当前富文本编辑器实例的内容(带html标签)
    };
    /**
	 * 自定义上传视频,仅mp4格式
	 *
	 * 视频上传接口
	 */
	function uploadVideo(file) {
		var formData = new FormData();
		formData.append('file', file);
		$.ajax({
			url: '/uploadVideo',                        //url
			type: 'post',                        //以post发送
			data: formData,             //要发送的数据。后端接收$_POST['user']
			dataType: 'json',                  //返回的数据类型
			cache: false,
			traditional: true,
			contentType: false,
			processData: false,
			success: function (res) {
				/*console.log(res);*/
				//图片上传成功之后的回调
				const range = quill.getSelection();
				if (range) {
					//将上传好的图片,插入到富文本的range.index(当前光标处)
					quill.insertEmbed(range.index, 'video', "" + res.src);
				}
			},
			error: function (e) {
				$.alert({
					title: 'Error',
					content: data.msg,
				});
			}
		});
	}
</script>
</body>
</html>

上传视频后端,这里笔者主要是通过文件的后缀名判断文件格式,因为这个视频需要有关联关系,要将其路径写入数据库,
所以会有数据库写入操作,如果大家没有这个需求的话可以把对应的代码删掉。

@RequestMapping("/uploadVideo")
    @ResponseBody
    public Map<String,String> upload(@RequestParam MultipartFile file, HttpServletRequest request){
        Integer user = (Integer) request.getSession().getAttribute("userId");
        Long userId = user.longValue();
        Map<String,String> data = new HashMap<>();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if ( suffix.equalsIgnoreCase("mp4") ){
            OutputStream os = null;
            InputStream inputStream = null;
            Long articleId = publishArticleService.whetherCreateArticle(userId);
            String fileName = ("video" + articleId) + System.currentTimeMillis() + "." + suffix;
            String videoUrl = articleSavePath + fileName;  //articleSavePath 代表/article/,写入数据库中的相对路径
            try {
                inputStream = file.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                byte[] bs = new byte[1024];
                int len;
                // 输出的文件流保存到本地文件
                File tempFile = new File(articleWritePath);  //articleWritePath代表"F:\\images\\article"
                if (!tempFile.exists()) {
                    tempFile.mkdirs();
                }
                os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
                // 开始读取
                while ((len = inputStream.read(bs)) != -1) {
                    os.write(bs, 0, len);
                }
                os.flush();
                articlePhotoService.insertVideo(videoUrl, articleId);
                data.put("src", videoUrl);
                return data;
            } catch (IOException e) {
                e.printStackTrace();
                data.put("msg","上传视频失败,请稍后重试!");
                return data;
            } catch (Exception e) {
                e.printStackTrace();
                data.put("msg","上传视频失败,请稍后重试!");
                return data;
            } finally {
                // 完毕,关闭所有链接
                try {
                    os.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else {
            data.put("msg","上传视频格式仅支持mp4!");  //可以上传什么格式,可以自定义判断
            return data;
        }
    }

最终效果:
在这里插入图片描述

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
vue2quill是一个基于Vue.js和Quill.js实现的富文本编辑器组件。它支持上传图片和视频,但需要你自己实现上传的逻辑。 对于上传视频的实现,你可以使用一些常用的视频上传方案,比如通过后端接口实现文件上传使用第三方云存储服务等。在vue2quill中,你需要做的就是通过配置参数来指定上传视频的接口地址或者上传视频的回调函数。 以下是一个使用vue2quill上传视频的示例代码: ``` <template> <div> <quill-editor v-model="content" :options="editorOption" @image-added="onImageAdded" @video-added="onVideoAdded"></quill-editor> </div> </template> <script> import QuillEditor from 'vue-quill-editor' export default { components: { QuillEditor }, data () { return { content: '', editorOption: { modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'], // remove formatting button ['link', 'image', 'video'] // link and image, video ] }, placeholder: '请输入正文', theme: 'snow' } } }, methods: { onImageAdded (file, callback) { // 处理图片上传 let formData = new FormData() formData.append('file', file) axios.post('/upload/image', formData) .then(res => { callback(res.data.url) }) }, onVideoAdded (file, callback) { // 处理视频上传 let formData = new FormData() formData.append('file', file) axios.post('/upload/video', formData) .then(res => { callback(res.data.url) }) } } } </script> ``` 在上述代码中,我们通过配置QuillEditor组件的options参数来设置富文本编辑器的选项,包括工具栏、占位符等。在onImageAdded和onVideoAdded回调函数中,我们可以处理上传图片和上传视频的逻辑,并通过callback函数将上传后的图片或视频的地址返回给富文本编辑器组件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高并发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值