summernote上传并回显图片、删除图片,并接收显示、只读

本文介绍如何使用Summernote富文本编辑器实现图文混排、图片上传及自定义配置等功能。通过前端代码示例和后端对接说明,帮助开发者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中文官网
官网:官网地址
首先掌握,不懂得地方进来看summernote基本使用

前端代码

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
	layout:decorator="base/base-layout">
<head>
	<meta charset="UTF-8">
  <title>Summernote</title>
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
</head>
<body>

	
	<form method="post">
	  <textarea id="summernote" name="editordata"></textarea>
	</form>
	<div>
		<input type="button" id="sub">
	</div>
		
	<script th:inline="javascript">
		//<![CDATA[
	$(document).ready(function() {
	
			$('#summernote').summernote({
			toolbar:[
			        ['style', ['style']],
			        ['font', ['bold', 'italic', 'underline', 'superscript', 'subscript', 'strikethrough', 'clear']],//加粗、斜体、下划线、删除线
			        ['fontname', ['fontname']],     
			        ['fontsize', ['fontsize']], 
			        ['color', ['color']],
			        ['para', ['ul', 'ol', 'paragraph']],
			        ['height', ['height']],
			        ['table', ['table']],
			        ['insert', ['link', 'picture', 'hr']], //, 'video'
			        ['view', ['fullscreen']],
			        ['help', ['help']]      
		      ],    
		      lang: 'zh-CN' ,// default: 'en-US'
			  placeholder: '输入文字或者相片',
       		  //tabsize: 2,
			  height: 300,                 // set editor height
			  minHeight: null,             // set minimum height of editor
			  maxHeight: null,             // set maximum height of editor
			  focus: true ,                 // set focus to editable area after initializing summernote
			  dialogsInBody: true,			// 不设置,会出现,点击 summernote 弹出窗口级联关闭父窗口问题
			  callbacks: {
	            onImageUpload: function(files, editor, $editable) {
	                sendFile(files);
	                
	            },
	            //删除图片时调用
				   	onMediaDelete: function(target){
						 removeImage(target[0].dataset.id);//$target[0]是当前对象img标签,获取data-id
					},
	          }
			});	
		
			$('#sub').click(function () {
				
				var content=$('#summernote').html()
			
				console.log(content)
				 	$.ajax({
		                    url:"/dev/josion/base/test",	
		                    type:"POST",
		                    data: {info : content},
		                    success: function(data){
								console.log(data)
							}
					})
				
			})
		
	});
	function sendFile(files, editor, $editable) {
		
	    var size = files[0].size;
	    if(size  > 5*1024*1024) {
	        alert("图片大小不能超过5M...");
	        return false;
	    }
	    //console.log("size="+size);
	    var formData = new FormData();
	    formData.append("file", files[0]);
	    $.ajax({
	        data : formData,
	        type : "POST",
	        url : "/dev/josion/base/file",    // 图片上传出来的url,返回的是图片上传后的路径,http格式
	        cache : false,
	        contentType : false,
	        processData : false,
	        dataType : "json",
	        success: function(data) {
	           // $('.summernote').summernote('insertImage',data);
	           console.log(data.data)
	           //var image= `<p><img src="/dev/assets/images/2022/01/12/3b42cb28-3d7b-46c3-8de4-07dd9c97200b.png"></p>	`//"<img src="+"file://,"+data.data+">"
	            
	            var image= `<p><img src="/dev/assets`+`${data.data}`+`"></p>	`//"<img src="+"file://,"+data.data+">"
	           

				//$('#summernote').summernote('insertImage', url, filename);插入图片,都行,但如果是static中的因为刷新问题不一定行
				$('#summernote').summernote('pasteHTML', image);
	           console.log("上传成功")
	        },
	        error:function(data){	
			console.log(data)
			console.log("上传失败")
	            //alert("上传失败");
	        }
	    });
		}
	     </script>
</body>
</html>

后端代码

@PostMapping("/base/test")
	public R<Boolean> base(Summernote summernote) {
		Boolean result = false;
		String localeMessage = "系统接受了您的操作";
		Integer rst = R.SUCCESS;

		System.out.println(summernote.getInfo());
		
		if(summernote.getInfo()==null)return new R<Boolean>(false, "参数为空", rst);
		
		String uid=UUID.fastUUID().toString();
		String info=summernote.getInfo();
		
		
		josionUserMapper.base(uid,info);
		
		
		return new R<Boolean>(result, localeMessage, rst);
	}
    
    
    private String tempFilePath = "E:/workspaces/test/src/main/resources/static/assets/images";
    
    @PostMapping("/base/file")
   	public  R<String> file(@RequestPart("file") MultipartFile file, HttpServletRequest request) throws FileNotFoundException {
    	 
    	        if(file == null || file.isEmpty()){
    	            return null;
    	        }
    	        //获取文件名
    	        String fileName = file.getOriginalFilename();
    	        //获取文件的后缀名	
    	        String suffixName = fileName.substring(fileName.lastIndexOf("."));
    	        //获取文件大小
    	        //int fileSize = (int)file.getSize();
    	        
    	        
    	        //获取日期
    			Date date = new Date();
    			SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd"); //new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    			String time  = formatDate.format(date).replaceAll("-", "/");
    			String r=UUID.fastUUID().toString();
    			String newFileName=r+suffixName;
    			
    	        //文件路径
    	        String path = tempFilePath+"/"+time+"/"+newFileName;
    	        
    	        File saveFilePath= new File(path);
    	        // 判断路径是否存在,如果不存在则创建
    	        if(!saveFilePath.getParentFile().exists()) {
    	        	saveFilePath.getParentFile().mkdirs();
    	        }
    	        try {
                    file.transferTo(saveFilePath);
    	        } catch (Exception e) {
    	        	 e.printStackTrace();
    	        	 return null;
    	        }
    	        
    	        
    	        
    	        
    	    String a="/images/"+time+"/"+newFileName;
    	  
    		return new R<String>(a, "完成", R.SUCCESS);
   	}

接收显示

同样,由summernote上传到后端保存的带标签的字符串,当前端接收到后端发来的还html标签的字符串是,直接

$('#summernote').summernote('pasteHTML', data);

就能搞定,包括像之类的直接显示图片

$('#lblQuestionV').summernote({
					airMode: true,
	               	disableDragAndDrop: true, //禁止拖放
	               	shortcuts: false,//禁止快捷键
               	});	
$('#summernote').summernote('disable');
let newCss = {};
newCss.backgroundColor = "white";
$('.note-editable').css(newCss);
$('#summernote').summernote('pasteHTML', data);
        		
 //$('#summernote').summernote('enable');//恢复编辑
扩展

删除图片
在这里插入图片描述

onImageUploadError //当图片上传发生错误时

常用规则

options: {
  modules: {
    'editor': Editor,
    'clipboard': Clipboard,
    'dropzone': Dropzone,
    'codeview': Codeview,
    'statusbar': Statusbar,
    'fullscreen': Fullscreen,
    'handle': Handle,
    // FIXME: HintPopover must be front of autolink
    //  - Script error about range when Enter key is pressed on hint popover
    'hintPopover': HintPopover,
    'autoLink': AutoLink,
    'autoSync': AutoSync,
    'placeholder': Placeholder,
    'buttons': Buttons,
    'toolbar': Toolbar,
    'linkDialog': LinkDialog,
    'linkPopover': LinkPopover,
    'imageDialog': ImageDialog,
    'imagePopover': ImagePopover,
    'videoDialog': VideoDialog,
    'helpDialog': HelpDialog,
    'airPopover': AirPopover
  },
 
  buttons: {},
  
  lang: 'zh-CN',
 
  // toolbar工具栏默认
  toolbar: [
    ['style', ['style']],
    ['font', ['bold', 'underline', 'clear']],
    ['fontname', ['fontname']],
    ['color', ['color']],
    ['para', ['ul', 'ol', 'paragraph']],
    ['table', ['table']],
    ['insert', ['link', 'picture', 'video']],
    ['view', ['fullscreen', 'codeview', 'help']]
  ],
 
  // popover
  popover: {
    image: [
      ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']],
      ['float', ['floatLeft', 'floatRight', 'floatNone']],
      ['remove', ['removeMedia']]
    ],
    link: [
      ['link', ['linkDialogShow', 'unlink']]
    ],
    air: [
      ['color', ['color']],
      ['font', ['bold', 'underline', 'clear']],
      ['para', ['ul', 'paragraph']],
      ['table', ['table']],
      ['insert', ['link', 'picture']]
    ]
  },
 
  // air mode: inline editor
  airMode: false,
 
  width: null,
  height: null,
 
  focus: false,
  tabSize: 4,
  styleWithSpan: false,
  shortcuts: true,
  textareaAutoSync: true,
  direction: null,
 
  styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
 
  fontNames: [
    'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New',
    'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande',
    'Tahoma', 'Times New Roman', 'Verdana'
  ],
 
  fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],
 
  // pallete colors(n x n)
  colors: [
    ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],
    ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],
    ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'],
    ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'],
    ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'],
    ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'],
    ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'],
    ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031']
  ],
 
  lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],
 
  tableClassName: 'table table-bordered',
 
  insertTableMaxSize: {
    col: 10,
    row: 10
  },
 
  dialogsInBody: false,
  dialogsFade: false,
 
  maximumImageFileSize: null,
 
  callbacks: {
    onInit: null,//初始化回调函数
    onFocus: null,//聚集
    onBlur: null,//失去焦点
    onEnter: null,//回车键的回调函数
    onKeyup: null,
    onKeydown: null,
    onSubmit: null,//提交时回调函数
    onImageUpload: null,//这就是上传图片的回调函数
    onImageUploadError: null//上传图片出错
  },
 
  codemirror: {
    mode: 'text/html',
    htmlMode: true,
    lineNumbers: true
  },
 
  keyMap: {
    pc: {
      'ENTER': 'insertParagraph',
      'CTRL+Z': 'undo',
      'CTRL+Y': 'redo',
      'TAB': 'tab',
      'SHIFT+TAB': 'untab',
      'CTRL+B': 'bold',
      'CTRL+I': 'italic',
      'CTRL+U': 'underline',
      'CTRL+SHIFT+S': 'strikethrough',
      'CTRL+BACKSLASH': 'removeFormat',
      'CTRL+SHIFT+L': 'justifyLeft',
      'CTRL+SHIFT+E': 'justifyCenter',
      'CTRL+SHIFT+R': 'justifyRight',
      'CTRL+SHIFT+J': 'justifyFull',
      'CTRL+SHIFT+NUM7': 'insertUnorderedList',
      'CTRL+SHIFT+NUM8': 'insertOrderedList',
      'CTRL+LEFTBRACKET': 'outdent',
      'CTRL+RIGHTBRACKET': 'indent',
      'CTRL+NUM0': 'formatPara',
      'CTRL+NUM1': 'formatH1',
      'CTRL+NUM2': 'formatH2',
      'CTRL+NUM3': 'formatH3',
      'CTRL+NUM4': 'formatH4',
      'CTRL+NUM5': 'formatH5',
      'CTRL+NUM6': 'formatH6',
      'CTRL+ENTER': 'insertHorizontalRule',
      'CTRL+K': 'linkDialog.show'
    },
 
    mac: {
      'ENTER': 'insertParagraph',
      'CMD+Z': 'undo',
      'CMD+SHIFT+Z': 'redo',
      'TAB': 'tab',
      'SHIFT+TAB': 'untab',
      'CMD+B': 'bold',
      'CMD+I': 'italic',
      'CMD+U': 'underline',
      'CMD+SHIFT+S': 'strikethrough',
      'CMD+BACKSLASH': 'removeFormat',
      'CMD+SHIFT+L': 'justifyLeft',
      'CMD+SHIFT+E': 'justifyCenter',
      'CMD+SHIFT+R': 'justifyRight',
      'CMD+SHIFT+J': 'justifyFull',
      'CMD+SHIFT+NUM7': 'insertUnorderedList',
      'CMD+SHIFT+NUM8': 'insertOrderedList',
      'CMD+LEFTBRACKET': 'outdent',
      'CMD+RIGHTBRACKET': 'indent',
      'CMD+NUM0': 'formatPara',
      'CMD+NUM1': 'formatH1',
      'CMD+NUM2': 'formatH2',
      'CMD+NUM3': 'formatH3',
      'CMD+NUM4': 'formatH4',
      'CMD+NUM5': 'formatH5',
      'CMD+NUM6': 'formatH6',
      'CMD+ENTER': 'insertHorizontalRule',
      'CMD+K': 'linkDialog.show'
    }
  },
  icons: {
    'align': 'icon-align',
    'alignCenter': 'icon-align-center',
    'alignJustify': 'icon-align-justify',
    'alignLeft': 'icon-align-left',
    'alignRight': 'icon-align-right',
    'indent': 'icon-indent-right',
    'outdent': 'icon-indent-left',
    'arrowsAlt': 'icon-resize-full',
    'bold': 'icon-bold',
    'caret': 'icon-caret-down',
    'circle': 'icon-circle',
    'close': 'icon-close',
    'code': 'icon-code',
    'eraser': 'icon-eraser',
    'font': 'icon-font',
    'frame': 'icon-frame',
    'italic': 'icon-italic',
    'link': 'icon-link',
    'unlink': 'icon-chain-broken',
    'magic': 'icon-magic',
    'menuCheck': 'icon-check',
    'minus': 'icon-minus',
    'orderedlist': 'icon-list-ol',
    'pencil': 'icon-pencil',
    'picture': 'icon-picture',
    'question': 'icon-question',
    'redo': 'icon-redo',
    'square': 'icon-square',
    'strikethrough': 'icon-strikethrough',
    'subscript': 'icon-subscript',
    'superscript': 'icon-superscript',
    'table': 'icon-table',
    'textHeight': 'icon-text-height',
    'trash': 'icon-trash',
    'underline': 'icon-underline',
    'undo': 'icon-undo',
    'unorderedlist': 'icon-list-ul',
    'video': 'icon-facetime-video'
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值