Java使用OpenOffice实现在线预览

公司业务:在线预览office文件,调研了一下,目前市场上免费的,比较合适的,也就是OpenOffice了,事已至此,干活。。。

思路:

1.利用 OpenOffice 以及 jodconverter 转换各种office文件为pdf格式

2.设置response的contentType为application/pdf,直接用IO将pdf文件输出就可以了(缺点:若用户使用ie浏览器则是下载而不是预览)

3.利用多进程--利用SpringMVC一个用户请求就有一个新的线程为此服务,但转换的openoffice进程只有一个,所以就算使用多线程还是相当于排队等一个转好了,下一个才会去转换。所以这里使用多进程(这里没有使用Process类)。

4.所有文件只转换一次--因为转换的pdf文件都放在某个目录下,所以只要我先判断对应的目录下有无该文件,若有就直接取出,若没有就去转换。

5.用锁处理并发转换问题--有这么一种情况,两个用户同时请求预览同一个文件,同时发现文件还为转换为pdf,同时去转换导致转换异常,这时可以考虑加锁去处理,如果有一方正在转换了,另一方就直接等待转换好去现成的就可以了

步骤:

1、去官网下载openOffice,并安装,下载地址:Apache OpenOffice - Official Download

2、引入相关jar,jar包不太好找,能从公共资源上pull下来的也就这些了,不过不用担心,对待普通的业务需求也够用了

 compile group: 'org.jodconverter', name: 'jodconverter-core', version: '4.0.0-RELEASE'
    compile group: 'org.openoffice', name: 'jurt', version: '3.0.1'
    compile group: 'org.openoffice', name: 'ridl', version: '3.0.1'
    compile group: 'org.openoffice', name: 'juh', version: '3.0.1'
    compile group: 'org.openoffice', name: 'unoil', version: '3.0.1'

3、controller层

//调用转换方法
File file= storeService.wordToPDF(key);

        if (file.exists()){
            byte[] data = null;
            try {
                FileInputStream input = new FileInputStream(file);
                data = new byte[input.available()];
                input.read(data);
                response.getOutputStream().write(data);
                input.close();
            } catch (Exception e) {
                System.out.println(e);
            }

        }

4、service层,用注解管理,开启、关闭进程

@Component
public class LocalFileService{
 
   
 private final static String PORTS = "ports";
    private final static String PROPERTIES_FILE_NAME = "openOffice.properties";
    private final static String[] ports =
            PropertiesUtil.getPropertyByFileAndName(PROPERTIES_FILE_NAME,PORTS).split(",");
    private static OfficeManager OfficeManager = null;
    public static BlockingQueue<OfficeManager> OfficeManagerQueue = new LinkedBlockingDeque<OfficeManager>();

@PostConstruct
    public  void getOfficeManager()  {
        DefaultOfficeManagerBuilder builder = new DefaultOfficeManagerBuilder();

        builder.setOfficeHome(getOfficeHome());

        for(String port : ports){
            builder.setPortNumbers(Integer.parseInt(port));
            OfficeManager = builder.build();
            try {
                OfficeManager.start();
                System.out.println("##############officeManager start !");
            } catch (OfficeException e) {
                //打印日志
                System.out.println("start openOffice Fail!");
                e.printStackTrace();
            }
            try {
                //都放入阻塞队列中
                OfficeManagerQueue.put(OfficeManager);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    @PreDestroy
    public  void destroyOpenOfficeService(){
        for(OfficeManager manager : OfficeManagerQueue){
            try {
                System.out.println("close all officeManager");
                manager.stop();
            } catch (OfficeException e) {
                System.out.println("officeManager stop fail!"+e.getMessage());
                e.printStackTrace();
            }
        }
    }

}

5、转换工具类核心代码

public  class Office2PDF {
        
        private static Lock lock = new ReentrantLock();
        private static Map fileMap = new ConcurrentHashMap<>(16);
        
        private Office2PDF(){}
        
        /**
         * 将office格式的文件转为pdf
         * @param sourceFilePath 源文件路径
         * @return
         */
        public static File openOfficeToPDF(String sourceFilePath,String saveDir){
            return office2pdf(sourceFilePath,saveDir);
        }

        /**
         * 将office文档转换为pdf文档
         * @param sourceFilePath 原文件路径
         * @return
         */
        public static File office2pdf(String sourceFilePath,String saveDir){
            OfficeManager officeManager = null;
            File sourceFile = new File(sourceFilePath);
            try{
                

              if(StringUtil.isEmpty(sourceFilePath))
                {
                    System.out.println("源文件路径为空");
                    //打印日志...
                    return null;
                }

                if(!sourceFile.exists())
                {
                    System.out.println("源文件不存在");
                    //打印日志...
                    return null;
                }
                /*转换后文件路径*/
                String afterConvertFilePath = getAfterConverFilePath(sourceFilePath,saveDir);

                officeManager = OfficeManagerQueue.take();
                System.out.println("blockingQueue taked , OfficeManagerQueue size :" + OfficeManagerQueue.size());
                return convertFile(sourceFile,afterConvertFilePath,sourceFilePath,officeManager);
            }catch (Exception e){
                e.printStackTrace();
                try {
                    OfficeManagerQueue.put(officeManager);
                    System.out.println("blockingQueue put , OfficeManagerQueue size :" + OfficeManagerQueue.size());
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }

                System.out.println("转换异常");
            }
            return null;
        }

        /**
         * 转换文件
         * @param sourceFile 原文件
         * @param afterConvertFilePath 转换后存放位置
         * @param sourceFilePath 原文件路径
         * @param officeManager 转换器
         * @return
         */
        public static File convertFile(File sourceFile,
                                       String afterConvertFilePath,String sourceFilePath,OfficeManager officeManager) throws OfficeException {
            File outputFile = new File(afterConvertFilePath);
            if(!outputFile.getParentFile().exists()){
                //如果上级目录不存在也就是E:/pdfFile这个文件夹不存在则创建一个
                outputFile.getParentFile().mkdirs();
            }
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            lock.lock();

            if(fileMap.containsKey(sourceFile.getName()))
            {
                lock.unlock();
                while(true) {
                    if (outputFile.exists()) {
                       // System.out.println("文件有了");
                        try {
                            OfficeManagerQueue.put(officeManager);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        return outputFile;
                    }else{
                        converter.convert(sourceFile,outputFile);
                        try {
                            OfficeManagerQueue.put(officeManager);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        return outputFile;
                    }
                }
            }
            else
            {
                fileMap.put(sourceFile.getName(),sourceFile.getName());
                if(outputFile.exists()){
                    lock.unlock();
                  //  System.out.println("文件有了");
                    try {
                        OfficeManagerQueue.put(officeManager);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return outputFile;
                }

            }
            lock.unlock();
            converter.convert(sourceFile,outputFile);
            try {
                OfficeManagerQueue.put(officeManager);
                //System.out.println("blockingQueue puted OfficeManagerQueue size :" + OfficeManagerQueue.size());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return outputFile;
        }

        /**
         * 获取转换后文件存放的路径
         * @param sourceFilePath 源文件
         * @return
         */
        public static String getAfterConverFilePath(String sourceFilePath,String saveDir){

            //截取源文件文件名
            String sourceFileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1);
            String suffStr=FileUtil.getFileSuffix(sourceFileName);
            String nowName=saveDir+"/"+ sourceFileName.replaceAll( suffStr,".pdf");
            return nowName;
        }

        /**
         * 获取openOffice的安装目录
         * @return
         */
        public static String getOfficeHome(){
            String osName = System.getProperty("os.name");
            if(Pattern.matches("Windows.*",osName))
            {
                return "C:/Program Files (x86)/openOffice 4";
            }
            else if(Pattern.matches("Linux.*",osName))
            {
                return "/usr/temp";
            }
            else if (Pattern.matches("Mac.*",osName))
            {
                return "/Application/openOfficeSoft";
            }
            return null;
        }
    }

6、读取properties文件的工具类

package com.yhb.vortex.util;

import java.io.FileInputStream;
  import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
  import java.util.Properties;

public class PropertiesUtil {
    private String properiesName = "";

             public PropertiesUtil() {

            }
    public PropertiesUtil(String fileName) {
                 this.properiesName = fileName;
           }
    public String readProperty(String key) {
                String value = "";
                 InputStream is = null;
                 try {
                        is = PropertiesUtil.class.getClassLoader().getResourceAsStream(
                                        properiesName);
                        Properties p = new Properties();
                        p.load(is);
                         value = p.getProperty(key);
                     } catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     } finally {
                        try {
                                 is.close();
                            } catch (IOException e) {
                              // TODO Auto-generated catch block
                               e.printStackTrace();
                             }
                   }
                 return value;
             }

            public Properties getProperties() {
               Properties p = new Properties();
                 InputStream is = null;
                 try {
                         is = PropertiesUtil.class.getClassLoader().getResourceAsStream(
                                        properiesName);
                        p.load(is);
                    } catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     } finally {
                        try {
                                 is.close();
                             } catch (IOException e) {
                                // TODO Auto-generated catch block
                                 e.printStackTrace();
                            }
                     }
                return p;
             }

             public void writeProperty(String key, String value) {
                 InputStream is = null;
                OutputStream os = null;
                Properties p = new Properties();
             try {
                         is = new FileInputStream(properiesName);
                       p.load(is);
                       os = new FileOutputStream(PropertiesUtil.class.getClassLoader().getResource(properiesName).getFile());

                       p.setProperty(key, value);
                        p.store(os, key);
                        os.flush();
                        os.close();
                     } catch (Exception e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     } finally {
                         try {
                               if (null != is)
                                        is.close();
                                 if (null != os)
                                         os.close();
                           } catch (IOException e) {
                             // TODO Auto-generated catch block
                              e.printStackTrace();
                             }
                    }

          }
    public static String getPropertyByFileAndName(String propertyName, String key){
        PropertiesUtil p=new PropertiesUtil(propertyName);
       return   p.readProperty(key);
    }
}

7、properties文件

ports=9001,9002,9003,9004

8、前端js代码

handleFilePreview:function(file){
     
      window.open("##填入你的controller路径##,"_blank");

      
      }

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值