Summernote 是一个简单灵活的所见即所得的 HTML 在线编辑器,基于JQuery 和 Bootstrap 构建,支持快捷键操作,提供大量可定制的选项。

官方API和插件下载

官网地址:http://summernote.org/getting-started/

下载地址:https://github.com/summernote/summernote/

效果图

上传图片

postgre 富文本 bootstrap富文本编辑器插件_bootstrap

调整图片大小,对齐方式

postgre 富文本 bootstrap富文本编辑器插件_bootstrap_02

文本输入与显示

postgre 富文本 bootstrap富文本编辑器插件_富文本编辑器_03

Summernote基本使用

引入对应的样式文件

<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet"> 
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.css" rel="stylesheet"> 
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.js"></script>

页面只需要给一个textarea标签,之后用JS渲染富文本编辑器,可以在textarea标签中设置默认内容。

<textarea id="summernote" class="summernote"></textarea>

通过JS渲染及设置富文本编辑器的属性。

$(function() {
    $('#summernote').summernote({
        height: 400,    //设置高度
        toolbar: [      //自定义工具栏
            ['style',['style']],
            ['font',['bold','underline','clear']],
            ['fontname',['fontname']],
            ['color',['color']],
            ['para',['ul','ol','paragraph', 'height', 'hr']],
            ['table',['table']],
            ['insert',['link','picture','video']],
            ['view',['fullscreen','codeview','help']]
        ],
        tabsize : 2,
        lang : 'zh-CN',
        callbacks : {     // 回调函数
            // 图片上传
            onImageUpload: function(files) {
                var formData = new FormData();
                formData.append("file", files[0]);
                $.ajax({
                    url: 'textEdit/imgUpload', //后台文件上传接口
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function (data) {
                        //图片插入到summernote中
                        $("#summernote").summernote('insertImage', data);
                    },
                    error: function () {
                        alert("上传失败")
                    }
                })
            },
            //清除word复制的格式
            onPaste: function (ne) {
                var bufferText = ((ne.originalEvent || ne).clipboardData || window.clipboardData).getData('Text/plain');
                ne.preventDefault ? ne.preventDefault() : (ne.returnValue = false);
                setTimeout(function () {
                    document.execCommand("insertText", false, bufferText);
                }, 10);
            }
        }
    });
});

toolbar设置工具栏功能控件,可以自定义,也可以使用默认的。

Summernote工具栏所有属性。

  • 插入
  • picture: 打开图像对话框
  • link: 打开链接对话框
  • video: 打开视频对话框
  • table: 插入表格
  • hr: 插入水平线
  • 字体样式
  • fontname: 设置字体系列
  • fontsize: 设置字体大小
  • color: 设置前景色和背景色
  • forecolor: 设置前景色
  • backcolor: 设置背景色
  • bold: 切换字体粗细
  • italic: 斜体
  • underline: 切换下划线
  • strikethrough: 切换删除线
  • superscript: 切换上标
  • subscript: 切换下标
  • clear: 清除字体样式
  • 段落样式
  • style: 格式化所选块
  • ol: 切换有序列表
  • ul: 切换无序列表
  • paragraph: 段落对齐下拉菜单
  • height: 设置行高
  • 杂项
  • fullscreen: 切换全屏编辑模式
  • codeview: 切换所见即所得和html编辑模式
  • undo: 撤消
  • redo: 重做
  • help: 打开帮助对话框

onImageUpload覆盖图片上传处理属性,默认会把图片转换为Base64格式,onImageUpload中可以设置用AJAX请求上传图片到本地。

后台图片上传imgUpload()方法,代码如下。

/**
 * 图片上传
 * @param file
 * @return
 */
@RequestMapping(value = "/imgUpload")
@ResponseBody
private Object imgUpload(MultipartFile file) {
    String uuid = UUID.randomUUID().toString()+".jpg";
    fileService.saveFile(file, uuid);
    return "http://localhost:8080/bootstrap/textEdit/download?uuid="+uuid;
}

/**
 * 图片下载
 * @param uuid
 * @param request
 * @param response
 */
@RequestMapping(value = "/download")
@ResponseBody
private void download(String uuid, HttpServletRequest request, HttpServletResponse response) {
    fileService.download(uuid, request, response);
}

上传成功返回下载地址,用于图片回显。

saveFile上传方法,download图片下载方法。代码如下。

// 图片存放位置
private final static String IMAGEPATH="E:\\bootstrap\\image";

//保存图片
@Transactional
public boolean saveFile(MultipartFile file, String uuid){
    try{
        File path = path(file.getContentType());
        String filename = file.getOriginalFilename();
        SysFile fileEntity = new SysFile();
        fileEntity.setFileName(filename);
        fileEntity.setUuid(uuid);
        String storeaddress = path.getAbsolutePath();
        fileEntity.setStoreaddress(storeaddress);
        File saveFile = new File(path,uuid);
        try {
            fileRepository.save(fileEntity);
            file.transferTo(saveFile);
            return true;
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
            return false;
        }
    }catch (Exception e){
        System.out.println("图片保存异常");
        return false;
    }
}

//图片地址是否存在
private File path(String filename) {
    File pat=new File("E:\\bootstrap");
    File path=new File(SysFileService.IMAGEPATH);
    if(!pat.isDirectory()) {
        pat.mkdir();
    }
    if(!path.isDirectory()) {
        path.mkdir();
    }
    return path;
}

/**
 * 下载
 * @param uuid
 * @param request
 * @param response
 */
public void download(String uuid, HttpServletRequest request, HttpServletResponse response) {
    SysFile fileentity = fileRepository.findByUuid(uuid);
    String filename = fileentity.getFileName();
    filename = getStr(request, filename);
    File file = new File(fileentity.getStoreaddress(), uuid);
    if(file.exists()) {
        FileInputStream fis;
        try {
            fis = new FileInputStream(file);
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition", "attachment; filename=" + filename );
            ServletOutputStream out = response.getOutputStream();
            byte[] buf = new byte[2048];
            int n = 0;
            while((n = fis.read(buf))!=-1){
                out.write(buf, 0, n);
            }
            fis.close();
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private String getStr(HttpServletRequest request, String fileName) {
    String downloadFileName = null;
    String agent = request.getHeader("USER-AGENT");
    try {
        if(agent != null && agent.toLowerCase().indexOf("firefox") > 0){
            //downloadFileName = "=?UTF-8?B?" + (new String(Base64Utils.encode(fileName.getBytes("UTF-8")))) + "?=";
            //设置字符集
            downloadFileName = "=?UTF-8?B?" + Base64Utils.encodeToString(fileName.getBytes("UTF-8")) + "?=";
        }else{
            downloadFileName =  java.net.URLEncoder.encode(fileName, "UTF-8");
        }
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return downloadFileName;
}

上传成功后 $("#summernote").summernote('insertImage', data);方法将图片插入到summernote中,data为返回的下载路径。可以看上传的后台方法。

如果没有定义onImageUpload属性,Summernote会自动把图片转换为Base64格式。

postgre 富文本 bootstrap富文本编辑器插件_富文本编辑器_04

onPaste清除word复制过来的格式。

渲染完成后一个完美的富文本编辑器就出来了。

postgre 富文本 bootstrap富文本编辑器插件_bootstrap_05

可以通过以下代码给编辑器初始值(也可以写入到初始容器中)

$('#summernote').code("Holle word");

通过以下代码获取富文本域中的内容。

var summernote = $('#summernote').summernote('code');

定义一个获取富文本域中内容的方法。将获取到的内容在控制台输出。可以在此方法中用AJAX请求将数据保存到数据库中。

function sub() {
    var summernote = $('#summernote').summernote('code');
    console.log(summernote);
}

在富文本编辑器中测试输入内容。

postgre 富文本 bootstrap富文本编辑器插件_上传_06

通过点击保存按钮获取到富文本编辑器中的内容,在控制台输出。

postgre 富文本 bootstrap富文本编辑器插件_富文本编辑器_07

注意:由于富文本内容有可能过多,数据库保存该字段,不能用String类型,长度不够,MySQL数据库可以用longtext类型。