summernote富文本编辑器
2017-04-29 21:53
344 查看
最近要做一个发布文章页面,在富文本编辑器中选中了summernote
比起ckeditor,summernote要简单很多,简单到只需引入css和js就可以了。
关于ckeditor的配置应用参考我之前写的文章
ckeditor系列文章
先看看summernote的效果
summernote见到到无需任何配置,引入css和js即可完成图文混排
官方示例
不过图片是base64编码的,如果要存数据库的话会有点大。
所以将图片上传到服务器然后返回路径即可。
具体的代码
springmvc处理图片上传
ImageUtil
比起ckeditor,summernote要简单很多,简单到只需引入css和js就可以了。
关于ckeditor的配置应用参考我之前写的文章
ckeditor系列文章
先看看summernote的效果
summernote见到到无需任何配置,引入css和js即可完成图文混排
官方示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Summernote</title> <link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet"> <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script> <script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script> <link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.css" rel="stylesheet"> <script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.js"></script> </head> <body> <div id="summernote"><p>Hello Summernote</p></div> <script> $(document).ready(function() { $('#summernote').summernote(); }); </script> </body> </html>
不过图片是base64编码的,如果要存数据库的话会有点大。
所以将图片上传到服务器然后返回路径即可。
第一步
重写图片上传回调函数callbacks : { onImageUpload : function(files) { // 图片上传方法 uploadImages(files); } },
第二步
insertImage将上传后的图片插入summernote编辑器中。mySummernote.summernote('insertImage',ctx + result.data[i].url, result.data[i].fileName);
具体的代码
$(document).ready(function() { // summernote var mySummernote = $('.summernote'); // summernote图文编辑器配置 mySummernote.summernote({ lang : 'zh-CN',// 语言 height : 300, // 高度 minHeight : 300, // 最小高度 placeholder : '请输入文章内容', // 提示 callbacks : { // 回调函数 // 上传图片时使用的回调函数 onImageUpload : function(files) { // 具体的上传图片方法 uploadImages(files); } }, // summernote自定义配置 toolbar: [ ['operate', ['undo','redo']], ['magic',['style']], ['style', ['bold', 'italic', 'underline', 'clear']], ['para', ['height','fontsize','ul', 'ol', 'paragraph']], ['font', ['strikethrough', 'superscript', 'subscript']], ['color', ['color']], ['insert',['picture','video','link','table','hr']], ['layout',['fullscreen','codeview']], ] }) // summernote具体的上传图片方法 function uploadImages(files) { // 这里files是因为我设置了可上传多张图片,所以需要依次添加到formData中 // 进度条 $("#loadingText").html("正在上传图片...0%"); $("#loadingToast").show(); // 上传图片的form var formData = new FormData(); for (f in files) { formData.append("file", files[f]); } // XMLHttpRequest 对象 var xhr = new XMLHttpRequest(); xhr.open("post", ctx + '/uploadImage', true); xhr.onreadystatechange = function(){ if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200){ console.info("上传完成"); var result = $.parseJSON(xhr.responseText); console.info(result); if (result.code == "200") { console.info("文件路径"); console.info(result); for (i in result.data) { // 调用insertImage将上传后的图片插入summernote编辑器中 mySummernote.summernote('insertImage',ctx + result.data[i].url, result.data[i].fileName); } $("#loadingToast").hide(); }else{ $("#loadingToast").hide(); toastr.error("图片上传失败:" + result.data); } } }; xhr.upload.addEventListener("progress", progressFunction, false); xhr.send(formData); } // 进度条 function progressFunction(evt) { if (evt.lengthComputable) { var completePercent = Math.round(evt.loaded / evt.total * 100)+ "%"; // console.info(completePercent); $("#loadingText").html("正在上传图片..." + completePercent); if(completePercent=="100%"){ $("#loadingText").html("图片上传成功,正在处理"); } } }; var ctx = $("#ctx").val().trim(); $("#publishArticleBtn").click(function(){ var name=$("#articleName").val().trim(); if(name.length==0){ NodeFocus($("#articleName")); return ; } if (mySummernote.summernote('isEmpty')) { toastr.error('请输入文章内容'); return; } var content = mySummernote.summernote('code'); alert("文章内容<br>"+content); }) });
springmvc处理图片上传
package com.jcms.controller.admin; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import com.jcms.context.BaseReturn; import com.jcms.context.Param; import com.jcms.util.ImageUtil; /** * 图片上传,有可能前端也要上传图片,所以没有以/admin管理 * * @author 程高伟 * @date 2017年3月27日 下午5:41:11 */ @Controller public class FileUploadController { /** * summernote图片上传处理,可以处理同时上传多张图片的情形 * * @param files * @param request * @return * @throws IOException */ @RequestMapping(value = "/uploadImage", method = RequestMethod.POST, produces = "application/json;charset=utf8") @ResponseBody public String uploadMultipleFileHandler(@RequestParam("file") MultipartFile[] files, HttpServletRequest request) throws IOException { List<Image> images = new ArrayList<>(); for (MultipartFile file : files) { String url = ImageUtil.saveImage(request, file, Param.IMAGE_UPLOAD); Image image = new Image(); image.setUrl(url); image.setFileName(file.getOriginalFilename()); images.add(image); } return BaseReturn.response(images); } public class Image { // 图片上传后的路径 private String url; // 上传图片的名称 private String fileName; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } @Override public String toString() { return "Image [url=" + url + ", fileName=" + fileName + "]"; } } }
ImageUtil
package com.jcms.util; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import net.coobird.thumbnailator.Thumbnails; public class ImageUtil { private final static Logger logger = LoggerFactory.getLogger(ImageUtil.class); /** * 上传图片的时候,保存文件到本地 * * @param request * @param file * @param uploadPath * 形如这样的/assets/upload/image/ * @return /assets/upload/image/abc.jpg * @throws IOException */ public static String saveImage(HttpServletRequest request, MultipartFile file, String uploadPath) { // 如果用的是Tomcat服务器,则文件会上传到\\%TOMCAT_HOME%\\webapps\\YourWebProject\\uploadPath\\文件夹中 String fileName = file.getOriginalFilename(); String fileExt[] = fileName.split("\\."); String ext = fileExt[fileExt.length - 1]; logger.debug("-----文件后缀:{}-----", ext); if (fileName.equals(ext)) { // 未知的文件类型 logger.error("-----未知的文件类型,文件没有后缀-----"); return null; } // String ext = file.getContentType().split("\\/")[1]; String newFileName = UUIDGenerator.getUUID() + "." + ext; String realPath = request.getServletContext().getRealPath(uploadPath); String filePathAndName = null; if (realPath.endsWith(File.separator)) { filePathAndName = realPath + newFileName; } else { filePathAndName = realPath + File.separator + newFileName; } logger.info("-----上传的文件:{}-----", filePathAndName); try { // 先把文件保存到本地 FileUtils.copyInputStreamToFile(file.getInputStream(), new File(realPath, newFileName)); } catch (IOException e1) { logger.error("-----文件保存到本地发生异常:{}-----", e1.getMessage()); } // 然后进行压缩处理 thumbImage(filePathAndName); return uploadPath + newFileName; } /** * 删除文件 * * @param request * @param filePath * @return */ public static boolean deleteFile(HttpServletRequest request, String filePath) { String realPath = request.getSession().getServletContext().getRealPath(filePath); logger.info("-----要删除文件的路径:{}-----", realPath); File file = new File(realPath); try { FileUtils.forceDelete(file); return true; } catch (IOException e) { logger.info("-----删除图片发生异常:{}-----", e.getMessage()); return false; } } /** * 图片压缩 大于2M的0.5压缩比 小于1M的0.8压缩比 * * @param imageRealPath * 图片在磁盘的绝对路径,比如C:\\file.jpg */ public static void thumbImage(String imageRealPath) { File file = new File(imageRealPath); if (file.length() >= 1024 * 1024 * 2) { thumbImage(imageRealPath, 0.5); } else if (file.length() < 1024 * 1024 * 2 && file.length() >= 1024 * 1024 * 1) { thumbImage(imageRealPath, 0.8); } else { thumbImage(imageRealPath, 1); } } public static void thumbImage(String imageRealPath, double size) { logger.info("进行图片压缩,路径:{},比例:{}",imageRealPath,size); if(size-1==0){ return; } try { Thumbnails.of(imageRealPath).scale(size).toFile(imageRealPath); } catch (IOException e) { logger.error("-----读取图片发生异常:{}-----", e.getMessage()); logger.info("-----尝试cmyk转化-----"); File cmykJPEGFile = new File(imageRealPath); try { BufferedImage image = ImageIO.read(cmykJPEGFile); ImageOutputStream output = ImageIO.createImageOutputStream(cmykJPEGFile); if (!ImageIO.write(image, "jpg", output)) { logger.info("-----cmyk转化异常:{}-----"); } Thumbnails.of(image).scale(0.4f).toFile(imageRealPath); logger.info("-----cmyk转化成功-----"); } catch (IOException e1) { logger.info("-----cmyk转化异常:{}-----", e1.getMessage()); } } } }
相关文章推荐
- summernote富文本编辑器配合validate表单验证无法进行表单提交的问题
- summernote富文本编辑器的基本使用
- summernote富文本编辑器配合validate表单验证无法进行表单提交的问题
- summernote富文本编辑器的使用
- summernote富文本编辑器
- [Summer in Lab] W1
- Google Summer of Code 2008
- 观《和莎莫的500天((500) Days of Summer)》有感
- Christian Louboutin Spring Summer 2011 Shoes Collection
- HIT summer training Contest 11 / B another number game
- 2012 MUTC 10 总结(The Final MUTC of this Summer)
- UVa 10057 - A mid-summer night's dream.
- OUC_Summer Training_ DIV2_#11 722
- Tri_integral Summer Training 7 总结
- 2010-07-05 14:18 Altium Designer Summer 9 Build 9.4.0.20159
- 2014-Summer-PK4(Team)
- BUPT Summer Journey #test3 A
- BUPT Summer Journey #test6 D
- CSDN Summer of Code 2014 Report #1: About a interactive Command Line App
- xtu summer individual 6 F - Water Tree