Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪

前置条件

  • 安装LibreOffice
  • 安装OpenOffice
  • 安装Unoconv
  • 安装ImageMagick.x86_64
  • 安装GraphicsMagick.x86_64

思路说明

office文档上传后,执行Shell脚本命令,转换文档

libreoffice命令:

//如果是Word文档,则转化为PDF ,如果是Excel,则转换为html(将pdf:writer_pdf_Export替换为html) ,{src}替换为待转换文档全路径+名称,{des}替换为转换后存放路径
command = "libreoffice --convert-to pdf:writer_pdf_Export {src} --outdir {des}";

openoffice命令:

//如果是Word文档,则转化为PDF ,如果是Excel,则转换为html(将pdf:writer_pdf_Export替换为html) ,{src}替换为待转换文档全路径+名称,{des}替换为转换后存放路径
command = "soffice --headless --invisible --convert-to pdf:writer_pdf_Export {src} --outdir {des} "

unoconv命令:

//老版本的Word可能转换异常,使用unoconv转换;{src}替换为待转换文档全路径+名称,{des}替换为转换后存放路径
command = "unoconv -f pdf {src} -o {des} ";

图片文档上传后,执行Shell脚本命令,压缩或裁剪图片

//裁剪图片目录,注意{src}原图片路径+命令 {des}目标图片路径+命令
command = "convert {src} -resize 240x160 {des} "

执行命令如下:

//Java执行操作系统Shell命令
Runtime.getRuntime().exec(command);

异常解决

注意是中文转化乱码的问题

解决思路一:安装中文包

//搜索libreoffice的中文包,如果有,安装即可
yum search libreoffice//搜索openoffice的中文包,如果有,安装即可
yum search openoffice//搜索unoconv的中文版,如果有,安装即可
yum search unoconv

举例:libreoffice的中文包,简体、繁体一并安装了,免得有些文档有繁体,转换后乱码

libreoffice-langpack-zh-Hans.x86_64 : Simplified Chinese language pack for LibreOffice
libreoffice-langpack-zh-Hant.x86_64 : Traditional Chinese language pack for LibreOffice

解决思路二:复制Windows上的字体包到Linux系统上并安装

具体方法:https://blog.csdn.net/Aria_Miazzy/article/details/103830850

转换代码

package org.jeecg.common.system.controller;import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.BashUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;import lombok.extern.slf4j.Slf4j;/*** <p>* 用户表 前端控制器* </p>** @Author scott* @since 2018-12-20*/
@Slf4j
@RestController
@RequestMapping("/sys/common")
public class CommonController {@Value(value = "${jeecg.path.upload}")private String uploadpath = "/root/jeecg/upFiles";@Value(value = "${jeecg.path.convert}")private String convert = "convert";/*** @Author 政辉* @return*/@GetMapping("/403")public Result<?> noauth()  {return Result.error("没有权限,请联系管理员授权");}/*** @function 上传函数* @param request* @param response* @return*/@PostMapping(value = "/upload")public Result<?> upload(HttpServletRequest request, HttpServletResponse response) {//定义返回结果Result<?> result = new Result<>();//定义上传区域块try {//获取上传目录String ctxPath = uploadpath;//定义文件名称String fileName = null;//定义图片名称String thumborName = null;//设置图片名称String thumborName100x60 =null;//定义图片名称String originName = null;//定义上传文件子目录String bizPath = "files";//获取当前时间String nowtime = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date());//获取文件上传目录File file = new File(ctxPath + File.separator + bizPath);//如果文件不存在,则创建文件根目录if (!file.exists()) {file.mkdirs();}//获取多媒体Request请求对象MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;// 获取上传文件对象MultipartFile mf = multipartRequest.getFile("file");//获取文件名String orgName = mf.getOriginalFilename();//获取文件类型String fileType = orgName.substring(orgName.indexOf(".")).toLowerCase();//重命名文件fileName = nowtime + "_" + orgName.substring(0, orgName.lastIndexOf(".")).replaceAll(" ","")  + fileType;//设置图片名称thumborName = nowtime  + "_" + orgName.substring(0, orgName.lastIndexOf(".")).replaceAll(" ","") + "_S240x160" + fileType;//设置图片名称thumborName100x60 = nowtime  + "_" + orgName.substring(0, orgName.lastIndexOf(".")).replaceAll(" ","") + "_S100x60" + fileType;//设置图片名称originName = nowtime  + "_" + orgName.substring(0, orgName.lastIndexOf(".")).replaceAll(" ","") + fileType;//设置保存路径String savePath = file.getPath() + File.separator + fileName;//设置可以执行保存的文件对象File savefile = new File(savePath);//执行保存文件操作FileCopyUtils.copy(mf.getBytes(), savefile);//设置应显示的文件保存路径String dbpath = bizPath + File.separator + fileName;//字符串\\转换为/if (dbpath.contains("\\")) {dbpath = dbpath.replace("\\", "/");}//定义待执行命令String command = null;//如果是Excel文档,则转化为Html,如果是Word文档,则转化为PDF文档,如果是PPT文档,则转化为PDF文档,如果是图片,则进行压缩处理if(fileType.equals(".xlsx") || fileType.equals(".xls")) {//如果是Excel文档,则转化为Htmlcommand = "libreoffice --convert-to html {src} --outdir {des}";} else if(fileType.equals(".doc")) {//老版本的Word可能转换异常,使用unoconv转换command = "unoconv -f pdf {src} -o {des} ";} else if(fileType.equals(".ppt")) {//老版本的Word可能转换异常,使用unoconv转换command = "unoconv -f pdf {src} -o {des} ";} else if(fileType.equals(".docx")){//如果是Word文档,则转化为PDFcommand = "libreoffice --convert-to pdf:writer_pdf_Export {src} --outdir {des}";} else if(fileType.equals(".pptx")){//如果是PPT文档,则转化为PDFcommand = "libreoffice --convert-to pdf:writer_pdf_Export {src} --outdir {des}";} else if(fileType.equals(".jpeg") || fileType.equals(".jpg") || fileType.equals(".gif") || fileType.equals(".png") || fileType.equals(".bmp")){//定义图片压缩脚本 规格240x160 //command = "convert -strip -interlace Plane -gaussian-blur 0.02 -quality 85% {src} {src}";command = "convert {src} -resize 240x160 {des} ".replace("{src}",ctxPath + File.separator + bizPath + File.separator + fileName).replace("{des}", ctxPath + File.separator + bizPath + File.separator + "images" + File.separator + thumborName);//执行图片压缩命令BashUtil.exec(command);//定义图片压缩脚本 规格100x60command = "convert {src} -resize 100x60 {des} ".replace("{src}",ctxPath + File.separator + bizPath + File.separator + fileName).replace("{des}", ctxPath + File.separator + bizPath + File.separator + "images" + File.separator + thumborName100x60);//执行图片压缩命令BashUtil.exec(command);//定义图片压缩脚本 规格1024x768command = "convert {src} -resize 1024x768 {des} ".replace("{src}",ctxPath + File.separator + bizPath + File.separator + fileName).replace("{des}", ctxPath + File.separator + bizPath + File.separator + "origin" + File.separator + originName);//执行图片压缩命令BashUtil.exec(command);//执行图片裁剪脚本BashUtil.exec("bash /root/jeecg/upFiles/files/thumbor.sh");} else {command = "";}//执行shell命令区域try{//设置命令中的src descommand = command.replace("{src}",ctxPath + File.separator + bizPath + File.separator + fileName);command = command.replace("{des}", ctxPath + File.separator + bizPath + File.separator + convert + File.separator);//打印日志log.info("command :" + command + " fileType:" + fileType + " ctxPath:" + ctxPath + " bizPath:" + bizPath + " fileName:" + fileName + " convert:" + convert) ;//先设置文档可读BashUtil.exec("chmod 755 -R " + ctxPath + File.separator + bizPath + File.separator + "*");//执行文档转换命令BashUtil.exec(command);//执行Git Push命令,将本次变动实时同步到远程Git仓库中BashUtil.exec("bash /root/jeecg/upFiles/files/start.sh");} catch (Exception e){log.error(e.getMessage(), e);}//设置返回消息result.setMessage(dbpath);//设置返回状态result.setSuccess(true);} catch (IOException e) {result.setSuccess(false);result.setMessage("保存文件异常");log.error(e.getMessage(), e);}//返回结果return result;}/*** 预览图片* 请求地址:http://localhost:8080/common/view/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}* * @param request* @param response*/@GetMapping(value = "/view/**")public void view(HttpServletRequest request, HttpServletResponse response) {// ISO-8859-1 ==> UTF-8 进行编码转换String imgPath = extractPathFromPattern(request);// 其余处理略InputStream inputStream = null;OutputStream outputStream = null;try {imgPath = imgPath.replace("..", "");if (imgPath.endsWith(",")) {imgPath = imgPath.substring(0, imgPath.length() - 1);}response.setContentType("image/jpeg;charset=utf-8");String localPath = uploadpath;String imgurl = localPath + File.separator + imgPath;inputStream = new BufferedInputStream(new FileInputStream(imgurl));outputStream = response.getOutputStream();byte[] buf = new byte[1024];int len;while ((len = inputStream.read(buf)) > 0) {outputStream.write(buf, 0, len);}response.flushBuffer();} catch (IOException e) {log.error("预览图片失败" + e.getMessage());// e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}}}/*** 下载文件* 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}* * @param request* @param response* @throws Exception */@GetMapping(value = "/download/**")public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {// ISO-8859-1 ==> UTF-8 进行编码转换String filePath = extractPathFromPattern(request);// 其余处理略InputStream inputStream = null;OutputStream outputStream = null;try {filePath = filePath.replace("..", "");if (filePath.endsWith(",")) {filePath = filePath.substring(0, filePath.length() - 1);}String localPath = uploadpath;String downloadFilePath = localPath + File.separator + filePath;File file = new File(downloadFilePath);if (file.exists()) {response.setContentType("application/force-download");// 设置强制下载不打开            response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));inputStream = new BufferedInputStream(new FileInputStream(file));outputStream = response.getOutputStream();byte[] buf = new byte[1024];int len;while ((len = inputStream.read(buf)) > 0) {outputStream.write(buf, 0, len);}response.flushBuffer();}} catch (Exception e) {log.info("文件下载失败" + e.getMessage());// e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}/***  把指定URL后的字符串全部截断当成参数 *  这么做是为了防止URL中包含中文或者特殊字符(/等)时,匹配不了的问题* @param request* @return*/private static String extractPathFromPattern(final HttpServletRequest request) {String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);}}
package org.jeecg.common.util;import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;import java.io.IOException;
import java.io.InputStream;/*** Bash命令行执行器* A001* A001A002* @Author zhangdaihao**/
@Slf4j
public class BashUtil {/*** @function 执行Shell脚本命令* @param command* @return*/public static boolean exec(String command) {//如果传入参数为空,则直接返回if(command.equals("") || command == null){return false;}//执行状态int exitStatus = 0;// Process可以控制该子进程的执行或获取该子进程的信息Process process;try {log.info("exec cmd : " + command);process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。// 下面两个可以获取输入输出流InputStream errorStream = process.getErrorStream();InputStream inputStream = process.getInputStream();} catch (IOException e) {log.error(" exec cmd error :" + command, e);return false;}try {exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束// 第二种接受返回值的方法int i = process.exitValue(); // 接收执行完毕的返回值log.debug("i----" + i);} catch (InterruptedException e) {log.error("InterruptedException  exec {}", command, e);return false;}if (exitStatus != 0) {log.error("exec cmd exitStatus {}", exitStatus);} else {log.debug("exec cmd exitStatus {}", exitStatus);}// 销毁子进程process.destroy();// 子进程设置为空process = null;//返回执行结果return true;}}

附件上传效果

预览效果

Tips:因为Office文档在上传完毕时,就已经转换为PDF,PDF文件的URL可以直接通过Iframe配在src进行预览

注意此处代码是上传文档后,就是实时同步执行转换PDF操作,但是如果文档过大,可以改为异步执行哈,不然上传的时候一直卡着,小于5M的文档可以,同步执行,转换过程大概就几秒钟,影响不大。

Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪_实现在线预览Office文档相关推荐

  1. 安卓WebView在线预览office文档功能实现

    *## 在线预览office文档 我就直奔主题吧!估计是目前最简单的了吧! 我也搜了很多资料不外乎2种 使用谷歌文档服务(google国内使用不了,各种试就是显示不出来,) mWebView.load ...

  2. Android实现在线预览office文档(Word,Pdf,excel,PPT.txt等格式)

    1.概述 我们都知道,Android原生并没有提供浏览office文档格式的相关Api,在安卓端想要实现在线预览office文档的功能显然很是复杂,我们手机安装QQ浏览器时,在手机打开office文档 ...

  3. web项目使用OpenOffice实现前端在线预览office文档(超详细)

    超详细的OpenOffice实现前端在线预览office文档记录 最近搞一个数字化共享平台,是一个java web项目,使用框架ssm,其中项目有一个需要在线预览PDF.excle.ppt.word文 ...

  4. 在线预览word文档

    在线预览word文档 在线预览word文档 Java 使用wps将word文件转换pdf文件 转成PDF 在线预览word(转成pdf)前端展示 欢迎来提更好的意见 在线预览word文档 昨天下午组长 ...

  5. axios文件上传 formdata_基于业务场景下的图片/文件上传方案总结

    图片/文件上传组是企业项目开发中必不可少的环节之一, 但凡涉及到用户模块的都会有图片/文件上传需求, 在很多第三方组件库(ant desigin, element ui)中它也是基础组件之一. 接下来 ...

  6. Springboot 超简单实现在线预览,Word文档 doc、xlsx、pdf、txt等

    前言 PDF.TXT 只要资源可访问,根本就不需要进行任何处理,直接访问查看就完事了. 也是因为这个PDF可以直接查看(现在浏览器基本支持了),那么我们实现Word文档在线预览,其实也是 把WORD文 ...

  7. web项目 在线预览doc文档

    在线预览word文档 前端代码 后台controller代码(使用Aspose.Words) 前端代码 在前端发送ajax请求,并展示后端生成的html临时文件 showFile:function(m ...

  8. 在线预览office文件

    通过微软公开的api接口,将文档的URL传入即可实现在线预览office文件,而不需要去下载文件. 同时,若是想做提供预览office办公软件的服务,直接调用接口即可,无需利用openoffice或者 ...

  9. 微软接口在线预览office文件

    通过微软公开的api接口,将文档的URL传入即可实现在线预览office文件,而不需要去下载文件. 同时,若是想做提供预览office办公软件的服务,直接调用接口即可,无需利用openoffice或者 ...

最新文章

  1. nyoj 16 矩形嵌套 (DAG上的DP)
  2. 几本推荐的Java书
  3. ubuntu清除无效的右键打开方式
  4. webview部分安卓机中文乱码
  5. 【Python 必会技巧】判断字符串是否为字母/数字/大小写/空白字符/有效标识符/可打印字符
  6. GRPC: 如何实现分布式日志跟踪?
  7. cmder 神器 +curl
  8. Vue登录注册,并保持登录状态
  9. 深度学习网络架构(三):VGG
  10. PythonHDF5目录
  11. 26个最好免费下载电子书(Ebooks)的网站
  12. 图的m着色问题回溯法求解
  13. java根据日期计算星期几_利用Java计算某个日期是星期几
  14. python中的scaler_【笔记】scikit-learn中的Scaler(归一化)
  15. 【jQWidgets】jqxGrid控件在页面上重新加载的问题
  16. 150 个 word 常用文书模板 推荐(附下载地址)
  17. 计算机毕业设计Java网上书店管理系统(源码+系统+mysql数据库+Lw文档)
  18. 鼠标停在按钮上 按钮变大
  19. 百度病了,必应挂了,Yandex疯了。
  20. 【ZHYP005】子涵优品开发日志

热门文章

  1. Linux文件的复制、删除和移动命
  2. ADO.NET 命名规范
  3. MySQL数据库备份的10个教程
  4. javascript 实现禁止右键,复制,选取文本 (兼容firefox,IE,chrome等主流浏览器)...
  5. 如何在手机上安装Ubuntu Touch 13.10
  6. Flex mp3播放
  7. 事务(注解声明式事务管理)
  8. 【今日CV 计算机视觉论文速览 第146期】Mon, 22 Jul 2019
  9. 【今日CV 视觉论文速览】22 Nov 2018
  10. 教资科一科二知识点 0312