1.从view访问到controller的思路

2.关于office转换为pdf

实现手段可以参见openoffice转pdf或者别的软件,网上有具体的转换手段,我这里不多说;

大概代码如下,这里的OfficeToPDFInfo是一个包含输入输入路径等的一个Bean:

/*** 将Office文档转换为PDF. 运行该函数需要用到OpenOffice, OpenOffice下载地址为* http://www.openoffice.org/* @param sourceFile*            源文件, 绝对路径. 可以是Office2003-2007全部格式的文档, Office2010的没测试. 包括.doc,*            .docx, .xls, .xlsx, .ppt, .pptx等. 示例: F:\\office\\source.doc* @param destFile*            目标文件. 绝对路径. 示例: F:\\pdf\\dest.pdf* @return      操作成功与否的提示信息. 如果返回 -1, 表示找不到源文件, 或url.properties配置错误; 如果返回 0,*            则表示操作成功; 返回1, 则表示转换失败*/private static int office2PDF(OfficeToPDFInfo officeToPDFInfo) {String sourceFile=officeToPDFInfo.sourceUrl;String destFile=officeToPDFInfo.destUrl;String OpenOffice_HOME=officeToPDFInfo.openOfficeHOME;try {File inputFile = new File(sourceFile);if (!inputFile.exists()) {return -1;// 找不到源文件, 则返回-1}// 如果目标路径不存在, 则新建该路径File outputFile = new File(destFile);if (!outputFile.getParentFile().exists()) {outputFile.getParentFile().mkdirs();}//= "D:\\Program Files\\OpenOffice.org 3";//这里是OpenOffice的安装目录, 在我的项目中,为了便于拓展接口,没有直接写成这个样子,但是这样是绝对没问题的// 如果从文件中读取的URL地址最后一个字符不是 '\',则添加'\'if (OpenOffice_HOME.charAt(OpenOffice_HOME.length() - 1) != '\\') {OpenOffice_HOME += "\\";}// 启动OpenOffice的服务String command = OpenOffice_HOME+ "program\\soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;StarOffice.ServiceManager\" -nofirststartwizard";Process pro = Runtime.getRuntime().exec(command);// connect to an OpenOffice.org instance running on port 8100OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1", 8100);connection.connect();// convertDocumentConverter converter = new OpenOfficeDocumentConverter(connection);//DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection); converter.convert(inputFile, outputFile);// close the connectionconnection.disconnect();// 关闭OpenOffice服务的进程pro.destroy();return 0;} catch (FileNotFoundException e) {e.printStackTrace();return -1;} catch (ConnectException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return 1;}
public class OfficeToPDFInfo {/*** 转换的来源路径*/public String sourceUrl; /*** 转换后的本地路径*/public String destUrl;/*** 这里是OpenOffice的安装目录*/public String openOfficeHOME;/*** 单个任务执行的超时时间;*/public Integer task_execution_timeout;}

3.转换队列

为了更加合理的利用资源,一个转换队列是必不可少的,这里用一个线程list作为线程队列,用另外一个线程来管理这个队列;

用一个map来记录相关的状态;

转换的自定义Properties,其中转换的并行度最好和其服务器的cpu虚拟核心数量相同:

public class OfficeToPDFProperty {/*** 转换后的本地保存文件夹*/public String destFolder;/*** 这里是OpenOffice的安装目录*/public String openOfficeHome="";/*** 单个任务执行的超时时间;*/public Integer task_execution_timeout=60000;/*** 同时转换的最大并发数量;*/public int maxThreadCount=0;/*** 转换完成的状态保持时间*/public int convertionStatusKeepTime=0;/*** 转换(包括失败),最多convertionTryCount次;*/public int convertionTryCount=0;/*** 当前pdf转换状态的最大保存数量,超过此数量后将会抛弃时间最久的状态;*/public int convertionStatusMaxCount=1000;/*** 被转换的office文档的文件最大大小,超过此大小后,将不会转换;* 默认100M,单位字节;*/public int fileMaxSize=104857600;
}

转换的线程管理:

public class OfficeToPDFService {/*** 将运行前的线程加入线程池,运行开始后移出线程池;线程池中保存的是当前等待转换的线程队列*/private static List<Thread> office2PDFThreadPool=new LinkedList<Thread>();/*** 当前正在运行的转换线程的数量*/private static int convertionCount=0; private static Thread initConvertionThread=null;/*** 初始化线程池的运行,每2秒钟,检查一次转换的线程池*/private static synchronized void initConvertionThreadPool(){OfficeToPDFProperty officeToPDFProperty=null;try {officeToPDFProperty = OfficeToPDFPropertyService.getOfficeToPDFProperty();} catch (InstantiationException | IllegalAccessException | IOException e1) {e1.printStackTrace();}final int maxCount=officeToPDFProperty.maxThreadCount;if(initConvertionThread==null){initConvertionThread=new Thread(new Runnable() {    @Overridepublic void run() {while(true){int i=0;if(getConvertionCount()<maxCount&&getThreadWaitCount()>i){Thread converThread=getOffice2PDFThreadByThreadPool(i);if(!converThread.isAlive()){converThread.start();                                 continue;}i++;}try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}});initConvertionThread.start();}}/*** 将状态为非结束状态的转换的文件加入转换池中* 只转换OfficeConverionStatus.NoStart的文件* @param path* @param desPath*/public static void addOfficeFileToConvertionThreadPool(final String path,final String desPath) {initConvertionThreadPool();final String originFileName=FileUtils.getFileNameByPath(path);OfficeConverionStatus status=MyConstants.getConvertionType(originFileName);if(status!=OfficeConverionStatus.NoStart)return;MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Ready);final Thread thread=new Thread(new Runnable() {            @Overridepublic void run() {decrementConvertionCount();try {       incrementConvertionCount();MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Converting);   OfficeToPDFProperty officeToPDFProperty=OfficeToPDFPropertyService.getOfficeToPDFProperty();OfficeToPDFInfo info=new OfficeToPDFInfo();info.destUrl=desPath;info.sourceUrl=path;info.openOfficeHOME=officeToPDFProperty.openOfficeHome;info.task_execution_timeout=officeToPDFProperty.task_execution_timeout;int result=1;int convertionTryCount=officeToPDFProperty.convertionTryCount;                   while(result!=0&&convertionTryCount-->0){try {result=office2PDF(info);} catch (Exception e) {e.printStackTrace();result=1;}                           }//end whileif(result==-1){MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.NoFile);                     }else if(result==1){MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Faild);}else if(result==0){MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Success);}               } catch (InstantiationException e) {e.printStackTrace();MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Faild);} catch (IllegalAccessException e) {e.printStackTrace();MyConstants.putConvertionStatus(originFileName, OfficeConverionStatus.Faild);} catch (IOException e) {e.printStackTrace();MyConstants.putConvertionStatus(originFileName,OfficeConverionStatus.Faild);}finally{                    removeThreadFromOffice2PDFThreadPool(Thread.currentThread());}                          }});addThreadTOOffice2PDFThreadPool(thread);}/*** 得到当前等待的线程的数量* @return*/public static synchronized int getThreadWaitCount(){return office2PDFThreadPool.size();}public static synchronized Thread getOffice2PDFThreadByThreadPool(int index) {return office2PDFThreadPool.get(index);}public static synchronized void addThreadTOOffice2PDFThreadPool(Thread office2pdfThread) {office2PDFThreadPool.add(office2pdfThread);       }private static synchronized void removeThreadFromOffice2PDFThreadPool(Thread office2pdfThread) {office2PDFThreadPool.remove(office2pdfThread);     }private synchronized static  int getConvertionCount() {return convertionCount;}private  synchronized static void incrementConvertionCount() {convertionCount = convertionCount+1;}private synchronized static void decrementConvertionCount(){convertionCount = convertionCount-1;}

4.转换状态的保存:

public class MyConstants {private static String[] officeFile=new String[]{"doc","docx","ppt","pptx","xls","xlsx"};public static String[] getOfficeFileExtentionNames(){return officeFile;}/*** 判断是否是office文件* @param path* @return*/public static boolean isOfficeFile(String path){if(StringJudgeUtils.isEmpty(path))return false;for(int i=0;i<officeFile.length;i++){String nameString=FileUtils.getFileExtension(path);if(nameString.equalsIgnoreCase(officeFile[i])){return true;}}return false;}/***用来保存转换的状态**/private static Map<String, OfficeConverionStatus> convertionTypes=new HashMap<String, OfficeConverionStatus>();/*** * @param originFileName 转换之前的文件名称* @return 当前转换的状态*/public static synchronized OfficeConverionStatus getConvertionType(String originFileName){OfficeConverionStatus converionStatus=convertionTypes.get(originFileName);if(converionStatus==null)converionStatus=OfficeConverionStatus.NoStart;return converionStatus;}/*** 加入新的转换状态的时候,会自动移出旧的状态;* @param originFileName* @param converionStatus 当前转换的状态*/public static synchronized void putConvertionStatus(String originFileName,OfficeConverionStatus converionStatus){convertionTypes.put(originFileName,converionStatus);putConvertionTime(originFileName, System.currentTimeMillis());}/*** 将指定文件名的状态移出* @param originFileName*/private static synchronized void removeConvertionStatus(String originFileName){convertionTypes.remove(originFileName);}/*** 保存线程转换的结束时间和线程转换的状态相对应,转换结束后24小时内没有访问结果的将会被清除;*/private static Map<String, Long> convertionTimeMap=new HashMap<String, Long>();/*** * @param originFileName 转换之前的文件名称* @return 当前转换的状态*/public static synchronized Long getConvertionTime(String originFileName){Long converionTime=convertionTimeMap.get(originFileName);if(converionTime==null)converionTime=new Date(2000,1,1).getTime();return converionTime;}public static synchronized int getConvertionTypesSize(){return convertionTypes.size();}/*** 加入新的转换状态的时候,会自动移出旧的状态;* 数量超过convertionStatusMaxCount会移出更多老旧状态* @param originFileName* @param cTime*/private static synchronized void putConvertionTime(String originFileName,Long cTime){convertionTimeMap.put(originFileName,cTime);Set<String> keySet=convertionTimeMap.keySet();OfficeToPDFProperty officeToPDFProperty;try {officeToPDFProperty = OfficeToPDFPropertyService.getOfficeToPDFProperty();int keepTimeLong=officeToPDFProperty.convertionStatusKeepTime;int convertionStatusMaxCount=officeToPDFProperty.convertionStatusMaxCount;List<String> removeKeyStrings=new ArrayList<String>();do{for(String key:keySet){Long timeLong=convertionTimeMap.get(key);                   if(System.currentTimeMillis()-timeLong>keepTimeLong){removeKeyStrings.add(key);}}    for(String key:removeKeyStrings){convertionTimeMap.remove(key);removeConvertionStatus(key);}keepTimeLong=(int)(keepTimeLong*0.95);}while(getConvertionTypesSize()>convertionStatusMaxCount);} catch (InstantiationException | IllegalAccessException | IOException e) {e.printStackTrace();}    }/*public static synchronized void removeConvertionTime(String originFileName){convertionTime.remove(originFileName);}*/}

5.小结

注意线程之间的加锁互斥,没有贴出的代码无关核心思想,因为时间原因,以后以机会可以做成模块,打包为jar形式,不过openoffice转pdf的时候,

遇到部分ppt文档可能会出现转换失败的情况;

office转pdf(在线预览)思路(java示例)相关推荐

  1. PDF在线预览(java实现)

    String fileName = getRequest().getParameter("filename"); //如路径 C:\\Users\\zj\\AppData\\Loc ...

  2. java实现word转pdf在线预览格式

    java实现word转pdf在线预览格式 前段时间的项目里涉及了此功能,调研过一些方案,踩过一些坑,一一总结在此. java转pdf的方案很多,但是很多都要收费,转pdf也有一些格式方面的问题. 方案 ...

  3. Java 实现word pdf在线预览

    Java 实现word pdf在线预览 最近项目有这个需求,查找了一些资料,在这整理一下. 首先,pdf的文件,浏览器本身支持预览,不需要做什么处理. controller: 简单说下思路:就是利用i ...

  4. office 文档 在线预览功能实现(word,excel,pdf,ppt等多种格式)——使用https://view.xdocin.com/view 提示文档过期——基础积累

    web实现office文档在线预览功能--基础积累 最近遇到一个需求,就是要实现多种文档链接的在线预览,最简单的方式就是通过window.open(url地址)的方式来实现. 但是如果要求是在一个弹窗 ...

  5. Java实现PDF在线预览

    Java实现PDF在线预览 前言:之前一直PDF一直是下载后再查看,一直在想如何如何在线预览,现已找到方法,作此笔记,也希望都对其他人有所帮助 代码实现 @Slf4j @Controller @Req ...

  6. office文档在线预览工具平台选型

    ​​​​​​在线预览原理 文档在线预览说明: 1.业务系统生成文档浏览地址,用户通过终端进行访 2.用户终端访问文档预览资源地址,请求文档解析器,解析器分为私有云和公有云部署,作用是将文档进行解析成x ...

  7. asp.net实现word、excel、ppt、pdf在线预览

    引言 之前项目需要,查找了office文档在线预览的解决方案,顺便记录一下,方便以后查询. 方案一 直接在浏览器中打开Office文档在页面上的链接.会弹出如下窗口: 优点:主流浏览器都支持. 缺点: ...

  8. html 在线预览pdf功能,html中在线预览pdf文件之pdf在线预览插件

    html中在线预览pdf文件之pdf在线预览插件 最近遇到一个需求,要在html页面查看pdf生成的pdf文件!javascript 翻来覆去找到两种办法 ,最后采用了jquery.media.js插 ...

  9. office web viewer实现office文档在线预览

    office web viewer实现office文档在线预览 office web viewer官网介绍 若要自行制作 URL,您可使用以下链接,其中 <文档位置> 是文档的 URL. ...

  10. [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你

    引言 之前项目需要,查找了office文档在线预览的解决方案,顺便记录一下,方便以后查询. 方案一 直接在浏览器中打开Office文档在页面上的链接.会弹出如下窗口: 优点:主流浏览器都支持. 缺点: ...

最新文章

  1. ASP.NET页面事件:顺序与回传详解
  2. PHP无限分类-PHP100代码篇
  3. 中国牙科用人工骨替代材料市场供需态势与未来投资方向分析报告2022年
  4. hook java_Java 实现 Hook 对鼠标键盘监听 - 沐早'S NOTEBOOK - CSDN博客
  5. win10输入法切换快捷键怎么设置
  6. 解决docker push镜像到私有仓库时的报错【http: server gave HTTP response to HTTPS client】
  7. linux过滤端口抓包_Linux抓包工具tcpdump使用总结,WireShark的过滤用法
  8. mysql 局域网存储_MySQL 存储过程
  9. Tomcat6.0配置集合
  10. SpringBoot加载自定义yml文件
  11. 通过QQ音乐接口,做的一个简易微信小程序播放器
  12. 批判性思维-真理连贯论
  13. 1.16 隐藏不需要打印的内容 [原创Excel教程]
  14. oracle exadata维保,EXADATA数据一体机巡检说明
  15. 迅捷fw325r虚拟服务器设置,迅捷FAST FW325R路由器无线桥接设置方法
  16. Skipping JaCoCo execution due to missing execution data file
  17. mysql insert on duplicate_一条Insert on duplicate引发的血案
  18. 利用python提取基因cDNA长度,exon数量,pep长度和PI
  19. 中国医科大学2021年12月《中医护理学基础》作业考核试题
  20. 对《爱、死亡和机器人》这篇文章的浅思

热门文章

  1. VLIW Microprocessor Hardware Design
  2. 《俞军产品方法论》阅读笔记2020-08-07
  3. python求最小公倍数_Python 最小公倍数算法
  4. 大白话讲解,大数据基本术语
  5. HTTP Live Streaming
  6. 中国移动一句话 苹果丢掉“两个诺基亚”_-Chaz-_新浪博客
  7. 十分钟django后台 simpleui -含自定义后台首页
  8. WSADATA 数据结构
  9. 应付职称评定的论文-《七星彩神经网络预测系统》原型开发构想
  10. jQuery从上手到飞天