CKeditor图片上传配置和自定义文件上传插件

CKeditor图片上传配置和自定义文件上传插件

一、图片上传的配置

在CKeditor的config.js文件中添加图片上传的配置

CKEDITOR.editorConfig = function( config ) {
	config.plugins =
		'basicstyles,' +
		'bidi,' +
		'blockquote,' +
		'clipboard,' +
		'colorbutton,' +
		'colordialog,' 
		'tableselection,' +
        // 其他的一些插件省略
		'tabletools,' +
		'toolbar,' +
		'undo,' +
		'uploadimage,' +
		'wysiwygarea';
	// %REMOVE_END%
	
	/** 上传图片的配置 start **/
    config.image_previewText=' ';
	config.filebrowserUploadMethod = 'form';
  	// 配置上传图片请求地址
	config.filebrowserImageUploadUrl="/api/common/uploadImage";
  	/** 上传图片的配置 end **/
};

后台使用的是springboot,上传图片的后台代码

controller:

@RestController
@RequestMapping(value = "/api/common")
public class CommonApi {

	/** 图片临时存储路径 **/
	@Value("${img.temp.save.path}")
	private String imgTempSavePath;
	
	/** 图片的访问路径 **/
	@Value("${img.visit.path}")
	private String imgVisitPath;

	private final static Logger LOG = LoggerFactory.getLogger(CommonApi.class);

	@Autowired
	private TranFileInfoService tranFileInfoService;
	
	/**
	 * 上传图片
	 * 
	 * @param file
	 */
	@RequestMapping(value = "/uploadImage")
	public void uploadImage(@RequestParam("upload") MultipartFile[] file, HttpServletRequest request,
			HttpServletResponse response, HttpSession session) {
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = null;
		// CKEditor提交的很重要的一个参数 ,回调函数的序号
		String callback = request.getParameter("CKEditorFuncNum");
		try {
			out = response.getWriter();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	
		// 上传目录地址
		String uploadDir = session.getServletContext().getRealPath("/") + "upload/";
		// 如果目录不存在,自动创建文件夹
		File dir = new File(uploadDir);
		if (!dir.exists()) {
			dir.mkdir();
		}
		try {
			for (int i = 0; i < file.length; i++) {
				String fileName = FileUtil.uploadImage(imgTempSavePath, file[i]);
				out.print("<script type=\"text/javascript\">");
				out.print("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'"
						+ imgVisitPath + fileName + "','')");
				out.print("</script>");
			}
		} catch (Exception e) {
			out.print("<script type=\"text/javascript\">");
			out.print("window.parent.CKEDITOR.tools.callFunction(" + callback + ",''," + "'文件上传失败!');");
			out.print("</script>");
		}
	}
}

工具类:

/**
 * 文件工具类
 * @author intecwh
 *
 */
public class FileUtil {
	
	private final static Logger LOG = LoggerFactory.getLogger(FileUtil.class);

	/**
	 * 上传图片工具类,返回图片名
	 * @return
	 */
	public static String uploadImage(String tempSavePath, MultipartFile imgFile) throws Exception {
		
		Date date = new Date();
		String fileName = ((Long)date.getTime()).toString() + imgSuffix(imgFile.getOriginalFilename());
		
		FileOutputStream fos = null;
		try {
			String path = createChildPath();
			File file = createFile(tempSavePath+path, fileName);
			LOG.info("图片名:{}", file.getName());
			
			fos = new FileOutputStream(file);
			IOUtils.copy(imgFile.getInputStream(), fos);
			LOG.info("图片上传成功");
			
			return path+file.getName();
		} catch (IOException ex) {
			ex.printStackTrace();
			LOG.error("文件创建失败");
			throw ex;
		} catch (Exception ex) {
			ex.printStackTrace();
			LOG.info("图片上传失败");
			throw ex;
		} finally {
			if(fos!=null) {
				fos.close();
			}
		}
	}
	
	/**
	 * 生成文件
	 * @param parentPath
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static File createFile(String parentPath, String fileName) throws Exception {
		
		File parentFile = new File(parentPath);
		if(!parentFile.exists()) {
			parentFile.mkdirs();
		}
		
		File file = new File(parentPath + fileName);
		do {
			if(file.exists()) {
				fileName = ((Long)new Date().getTime()).toString() + imgSuffix(fileName);
				file = new File(parentPath + fileName);
			} else {
				file.createNewFile();
				return file;
			}
		} while(true);
	}
	
	/**
	 * 生成子路径
	 * @return
	 */
	public static String createChildPath() {
		
		String[] strings = {
				"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", 
				"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
				"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
		
		StringBuffer sb = new StringBuffer();
		Integer num = 0;
		for(int i=0; i<3; ++i) {
			for(int j=0; j<2; ++j) {
				num = (int)Math.floor(Math.random()*strings.length);
				sb.append(strings[num]);
			}
			sb.append("/");
		}
		
		return sb.toString();
	}
	
	/**
	 * 获取图片的格式,带点,例如:.jpg
	 * @param imgName
	 * @return
	 */
	public static String imgSuffix(String imgName) throws Exception {
		
		if(StringUtils.isEmpty(imgName)) {
			LOG.error("图片名为空");
			throw new RuntimeException("图片名为空");
		}
		
		return imgName.substring(imgName.indexOf("."));
	}
}

结果封装类ResultDto:

/**
 * 结果封装类
 * Created by Administratoron 2018/12/18
 **/
public class ResultDto<T> {

    private boolean successFlag;

    private T data;

    public static <T> ResultDto success() {

        ResultDto resultDto = new ResultDto();
        resultDto.setSuccessFlag(true);

        return resultDto;
    }

    public static <T> ResultDto<T> success(T data) {

        ResultDto<T> resultDto = new ResultDto<>();
        resultDto.setSuccessFlag(true);
        resultDto.setData(data);

        return resultDto;
    }

    public static <T> ResultDto fail() {

        ResultDto resultDto = new ResultDto();
        resultDto.setSuccessFlag(false);

        return resultDto;
    }

    public static <T> ResultDto<T> fail(T data) {

        ResultDto<T> resultDto = new ResultDto<>();
        resultDto.setSuccessFlag(false);
        resultDto.setData(data);

        return resultDto;
    }

    public boolean isSuccessFlag() {
        return successFlag;
    }

    public void setSuccessFlag(boolean successFlag) {
        this.successFlag = successFlag;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

如果图片是上传到本地,可以配置一下静态资源映射,这样,当我们访问指定的URL时,会到指定的本地磁盘中找图片:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
	
	@Autowired
    private StringToDateConverter stringToDateConverter;

    /** 图片临时存储路径 **/
	@Value("${img.temp.save.path}")
	private String imgTempSavePath;
	
	/** 图片最终存储路径 **/
	@Value("${img.fin.save.path}")
	private String imgFinSavePath;
	
	/** 图片的访问路径 **/
	@Value("${img.visit.path}")
	private String imgVisitPath;
    
    /**
     * 静态资源映射
     */
    @Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// TODO Auto-generated method stub
      	registry
          .addResourceHandler(imgVisitPath+"**")
          .addResourceLocations("file:"+imgTempSavePath+"/")
          .addResourceLocations("file:"+imgFinSavePath+"/");
      
		super.addResourceHandlers(registry);
	}
}

配置文件:

# 图片的临时存储路径
img.temp.save.path=E:/img/temp/
# 图片的最终保存路径
img.fin.save.path=E:/img/fin/
# 图片的访问路径
img.visit.path=/com/intec/
# 文件的保存路径
file.save.path=E:/file/
二、自定义文件上传插件

在CKeditor的plugins目录下面新建文件夹,文件夹的名字是自定义的插件名,结构如下:
在这里插入图片描述
uploadFile中的plugin.js:

CKEDITOR.plugins.add('uploadFile', {
    init: function (editor) {

        // 防止重复提交Ajax请求
        var flag=false;

        // 在toolbar中添加上传图片的插件按钮
        editor.ui.addButton( 'uploadFile', {
            label: '上传文件', // 调用时显示的名称
            command: 'uploadFile',
            toolbar: 'insert',
            icon: this.path + 'icons/uploadFile.png' // 在toolbar中的图标
        });

        editor.addCommand('uploadFile', {
           exec: function(editor) {
               // 获取富文本中选中的文本
               var text = editor.getSelection().getSelectedText();
               if(!isNotEmpty(text)) {
                   alert("请选择一段文字作为下载链接。");
                   return;
               }

             	/**
             	* 页面中要有一个form,向引入的页面中的form中添加一个input:
             	* <input type="file" id="uploadFile" style="display: none" />
             	**/
               var input = document.createElement( 'input' );
               input.setAttribute("type", "file");
               input.setAttribute("id", "uploadFile");
               input.style.display = 'none';
               document.getElementsByTagName("form")[0].prepend(input);

               // 上传文件
               $("#uploadFile").unbind("change").on('change', function() {
                   if(flag) {
                       alert("正在上传文件,请稍后再试");
                       return;
                   }
                   flag = true;
                   var formData = new FormData();
                   formData.append("file",  $("#uploadFile")[0].files[0]);

                   $.ajax({
                       type: 'POST',
                       url: '/api/common/uploadFile',
                       data: formData,
                       cache: false,
                       processData: false,
                       contentType: false,
                       success: function(result) {
                           if(result.successFlag) {
                               alert("文件上传成功");
                               // 将我们选择的文本替换成超链接
                               var a = editor.document.createElement( 'a' );
                             // 将返回的文件名拼接到超链接的href中,当我们在页面中点击超链接时可以下载文件
                               a.setAttribute("href", "/api/common/downloadFile/"+result.data);
                               a.setText(text);
                               editor.insertElement(a);
                           } else {
                               alert(result.data);
                           }
                       },
                       error: function () {
                           alert("文件上传失败!");
                       },
                       complete: function () {
                           flag = false;
                       }
                   });
               });

               $("#uploadFile").click();
           }
        });

        // 判断字符串去前后空格后是否不为空字符串
        function isNotEmpty(str) {

            if(str==null || str=="" || str==undefined) {
                return false;
            }

            // 去前后空格
            str = $.trim(str);
            if(str=="") {
                return false;
            }

            return true;
        }
    }
});

然后将我们自定义的文件上传插件添加到config.js中,在config.js中加入代码:

// 添加自定义插件
config.extraPlugins = 'uploadFile';

上传文件和点击超链接下载文件的后台代码:

@RestController
@RequestMapping(value = "/api/common")
public class CommonApi {

    /** 文件的保存路径 **/
	@Value("${file.save.path}")
	private String fileSavePath;

	private final static Logger LOG = LoggerFactory.getLogger(CommonApi.class);


	/**
	 * 上传文件
	 * @param file
	 * @return
	 */
	@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
	public ResultDto uploadFile(@RequestParam("file") MultipartFile file) {

		if(file!=null) {
			String fileName = file.getOriginalFilename();
			// 上传文件,并返回新生成的文件编号
			String fileNo = FileUtil.uploadFile(fileSavePath, file);
			if(StringUtils.isEmpty(fileNo)) {
				LOG.info("文件上传失败");
				return ResultDto.fail("文件上传失败");
			}

            // 将文件编号和文件名保存到数据库中
			tranFileInfoService.insert(fileNo, fileName);
          
			LOG.info("文件上传成功,文件编号:", fileNo);
			return ResultDto.success(fileNo);
		}

		return ResultDto.fail("请上传一个文件");
	}

	/**
	 * 下载文件
	 * @param fileNo:文件编号
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/downloadFile/{fileNo}")
	public void downloadFile(@PathVariable String fileNo, HttpServletRequest request, HttpServletResponse response) {

		try {
			TranFileInfo tranFileInfo = tranFileInfoService.getByFileNo(fileNo);
			if(tranFileInfo==null) {
				LOG.info("编号为:{} 的文件不存在", fileNo);
				return;
			}
			response.setContentType("application/octet-stream");
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			// 解决下载的文件的文件名出现中文乱码
			response.setHeader("Content-disposition", "attachment;filename="+new String(tranFileInfo.getFileName().getBytes("gb2312"), "ISO8859-1" ));
			response.flushBuffer();

			// 获取文件
			File file = new File(fileSavePath + tranFileInfo.getFileNo() + "." + tranFileInfo.getType());
			//  将文件下载到本地
			DataInputStream in = new DataInputStream(new FileInputStream(file));
			//输出流
			OutputStream out = response.getOutputStream();
			//输出文件
			int bytes = 0;
			byte[] bufferOut = new byte[1024];
			while ((bytes = in.read(bufferOut)) != -1) {
				out.write(bufferOut, 0, bytes);
			}
			LOG.info("编号为:{} 的文件下载成功,文件名:{}", tranFileInfo.getFileNo(), tranFileInfo.getFileName());
			out.close();
			in.close();
		} catch (Exception ex) {
			LOG.info("编号为:{} 的文件下载失败", fileNo);
			ex.printStackTrace();
		}
	}
}

上传按钮图片:在这里插入图片描述

富文本样式
在这里插入图片描述

选中富文本中的内容,点击下载文件的按钮,会提示我们上传文件
在这里插入图片描述

文件上传完成后,会提示我们文件上传成功后上传失败
在这里插入图片描述

此时查看源码,就会发现我们选中的文本变成了超链接
在这里插入图片描述

点击页面上的超链接会下载文件
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值