openoffice实现word文档转pdf,并实现预览功能

之前写的一篇文件转pdf,页面实现预览功能,访问项目外的静态资源解决方法很不幸的失败了,原因是本地服务器使用的是tomcat,可以很方便的通过设置虚拟路径实现页面对本地文件的访问,但是正式服务器使用的是websphere,设置虚拟路径的方式及其复杂(服务器知识不够),所以采用了代码的方式实现预览,方法如下:

pom.xml引入相关依赖

<dependency>
            <groupId>org.jodconvertergroupId>
            <artifactId>jodconverter-localartifactId>
            <version>4.2.2version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-apiartifactId>
                    <groupId>org.slf4jgroupId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.jodconvertergroupId>
            <artifactId>jodconverter-coreartifactId>
            <version>4.2.2version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-apiartifactId>
                    <groupId>org.slf4jgroupId>
                exclusion>
            exclusions>
        dependency>
        
        
        <dependency>
            <groupId>com.artofsolvinggroupId>
            <artifactId>jodconverter-maven-pluginartifactId>
            <version>2.2.1version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-apiartifactId>
                    <groupId>org.slf4jgroupId>
                exclusion>
                <exclusion>
                    <artifactId>ridlartifactId>
                    <groupId>org.openofficegroupId>
                exclusion>
                <exclusion>
                    <artifactId>juhartifactId>
                    <groupId>org.openofficegroupId>
                exclusion>
                <exclusion>
                    <artifactId>unoilartifactId>
                    <groupId>org.openofficegroupId>
                exclusion>
                <exclusion>
                    <groupId>org.slf4jgroupId>
                    <artifactId>slf4j-jdk14artifactId>
                exclusion>
            exclusions>
        dependency>

因为项目中使用的slf4j版本是1.7.21,这里发生了jar包冲突,请根据实际情况选择是否需要排除

2.本地项目启动时通过代码启动openoffice服务,项目组有个大神自定义了DispatcherServlet,所以我选择的是在spring容器初始化时启动,代码如下:

  • 相关配置prop.properties:
# 本地为0,测试及正式环境为1
serverType=0
#openoffice在本地的路径
openOfficePath = D://RICHENINFO/openoffice4
  • 初始化启动openoffice,这里只在本地环境下启动openoffice服务,测试及正式环境通过命令启动
public class CustomDispatcherServlet extends HttpServlet {
     

	private LocalOfficeManager officeManager;
    private String serverType;

	@Override
	public void init(ServletConfig config)  throws ServletException {
     
		initOpenOffice();
	}
	
	@Override
	public void destroy() {
     
		// 本地服务销毁时,停止openOffice服务
        if ("0".equals(serverType)) {
     
            OfficeUtils.stopQuietly(officeManager);
        }
	}
	private void initOpenOffice() {
     
	        String openOfficePath = null;
	        try {
     
	        // 读取配置文件
	            Properties properties = PropertiesLoaderUtils.loadAllProperties("prop.properties");
	            openOfficePath = properties.getProperty("openOfficePath");
	            serverType = properties.getProperty("serverType");
	        } catch (Exception e) {
     
	            e.printStackTrace();
	            return;
	        }
	        // 服务器类型为本地,通过代码启动openoffice服务
	        if ("0".equals(serverType)) {
     
	            // 如果openOffice服务已启动,不再执行启动代码
	            if (officeManager != null && officeManager.isRunning()) {
     
	                return;
	            }
	            officeManager = LocalOfficeManager.builder().officeHome(openOfficePath).install().build();
	            try {
     
	                officeManager.start();
	            } catch (OfficeException e) {
     
	                e.printStackTrace();
	                return;
	            }
	        }
	    }
	}
}

3.服务器配置openoffice

  • 上传openoffice安装包/wasapp/

  • 解压、安装openoffice

    tar -xvzf Apache_OpenOffice_4.1.3_Linux_x86-64_install-deb_zh-CN.tar.gz 
    cd zh-CN/RPMS/
    rpm -ivh *.rpm
    cd desktop-integration
    rpm -ivh openoffice4.1.3-redhat-menus-4.1.3-9783.noarch.rpm
    

    安装后的openoffice在opt/openoffice4目录

  • openoffice赋权

    安装后的权限为root,需要为was用户赋权,执行以下命令

    • mv /opt/openoffice /wasapp/

    • chown -R was:wasgroup /wasapp/openoffice4

    • ls -lrt 查看文件夹权限,看到权限归属为was,即赋权成功

      [was@cs-mz-wastest-rz-4 wasapp]$ cd openoffice4/
      [was@cs-mz-wastest-rz-4 openoffice4]$ ls -lrt
      total 60
      drwxr-xr-x 16 was wasgroup  4096 Oct 23  2018 presets
      drwxr-xr-x 22 was wasgroup  4096 Oct 23  2018 share
      -r--r--r--  1 was wasgroup 10470 Oct 23  2018 README.html
      -r--r--r--  1 was wasgroup  9925 Oct 23  2018 README
      drwxr-xr-x  3 was wasgroup  4096 Sep 10 20:21 help
      drwxr-xr-x  2 was wasgroup  4096 Sep 10 20:21 readmes
      drwxr-xr-x  6 was wasgroup 20480 Sep 10 20:21 programo
      
      
  • 启动openoffice服务以was用户启动服务,否则会因权限问题无法读取pdf文件,执行exit退出root用户

    • cd /wasapp/openoffice4/program

    • ./soffice --headless --accept=“socket,host=127.0.0.1,port=8100;urp;” --nofirststartwizard &

    • ps -ef | grep office 控制台输出以下内容即启动成功

      [was@cs-mz-wastest-rz-4 ~]$ ps -ef | grep office
      was      24466     1  0 15:05 ?        00:00:00 /bin/sh ./soffice -headless -accept=socket,host=127.0.0.1,port=8100;urp; -nofirststartwizard
      was      24475 24466  0 15:05 ?        00:00:06 /wasapp/openoffice4/program/soffice.bin -headless -accept=socket,host=127.0.0.1,port=8100;urp; -nofirststartwizard
      was      27500 27474  0 15:36 pts/0    00:00:00 grep --color=auto office
      
      
  • 停止服务

    • ps -ef | grep office 获取进程pid
    • kill -9 进程pid

4.调用openoffice服务转换文档

  • 核心代码如下
/**
  * 
  * @param inputPath 原始文件的路径
  * @param outputPath 输出pdf的路径
  */
private static void convert(String inputPath, String outputPath) {
     
        String openOfficePath = null;
        String serverType = null;
        try {
     
            Properties properties = PropertiesLoaderUtils.loadAllProperties("prop.properties");
            openOfficePath = properties.getProperty("openOfficePath");
            serverType = properties.getProperty("serverType");
        } catch (Exception e) {
     
            e.printStackTrace();
            return;
        }

        File inputFile = new File(inputPath);
        File outputFile = new File(outputPath);
        if (outputFile.exists()) return;

        if (inputPath.endsWith(".zip") || inputPath.endsWith(".rar")) return;
        // linux 使用以下代码
        // 连接服务,本地启动openoffice的默认端口是2002,命令启动的默认端口是8100
        int port = 8100;
        if ("0".equals(serverType)) {
     
            port = 2002;
        }
        OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1",port);
        try {
     
            connection.connect();
        } catch (ConnectException e) {
     
            System.err.println("文件转换出错,请检查OpenOffice服务是否启动。");
        }
        // convert 转换
        DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
        converter.convert(inputFile, outputFile);
        connection.disconnect();
    }

5.实现pdf预览

步骤3启动服务并将服务启动权限更改为了was用户,所以这里可以通过输入流直接读取到文件,再以流的形式输出到浏览器,通过标签请求即可实现pdf预览,java代码如下

 // 请求pdf文件
    @RequestMapping(value = "/getPdf")
    public void getKnowledgeText(@RequestParam(value = "pdfPath") String pdfPath, HttpServletRequest req, HttpServletResponse res) {
     
        File file = new File(pdfPath);
        res.setContentType("application/pdf");
        InputStream is = null;
        OutputStream os = null;

        try {
     
            is =  new FileInputStream(file);

            os = res.getOutputStream();

            byte[] bytes = new byte[1024*1024];
            int c = -1;
            int x = 0;
            while ((c = is.read(bytes)) != -1) {
     
                x = x + c;
                os.write(bytes, 0, c);
            }
            os.flush();
        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
     
            try {
     
                if (os != null) {
     
                    os.close();
                }
                if (is != null) {
     
                    is.close();
                }
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
    }

到此,通过openoffice实现文档转pdf、预览pdf功能实现

你可能感兴趣的:(学习,经验总结,java)