最近遇到一个项目需要把word转成pdf,GOOGLE了一下网上的方案有很多,比如虚拟打印、给word装扩展插件等,这些方案都依赖于ms word程序,在java代码中也得使用诸如jacob或jcom这类Java COM Bridge,使得服务器受限于win平台,而且部署起来也很麻烦。后来在某外文论坛看到了一个openoffice+jodconverter的转换方案,可以用纯的java代码完成转换工作,服务器端需要安装openoffice,但是需求一步额外的操作--需要在服务器上的某个端口提供一个openoffice服务,这对部署起来显得麻烦了点。
偶然机会发现了google code上有一个jodconverter 3,此版完全把2给重构了,它可以帮你创建oo服务监听在指定端口.
以下为官网介绍:
JODConverter automates conversions between office document formats using OpenOffice.org or LibreOffice.
Supported formats include OpenDocument, PDF, RTF, HTML, Word, Excel, PowerPoint, and Flash.
It can be used as a Java library, a command line tool, or a web application.
JODConverter 3.0 requires:
package org.artofsolving.jodconverter.sample.web; import java.io.File; import java.util.logging.Logger; import javax.servlet.ServletContext; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.artofsolving.jodconverter.OfficeDocumentConverter; import org.artofsolving.jodconverter.office.ManagedProcessOfficeManager; import org.artofsolving.jodconverter.office.ManagedProcessOfficeManagerConfiguration; import org.artofsolving.jodconverter.office.OfficeConnectionMode; import org.artofsolving.jodconverter.office.OfficeManager; public class WebappContext { public static final String PARAMETER_OFFICE_PORT = "office.port"; public static final String PARAMETER_OFFICE_HOME = "office.home"; public static final String PARAMETER_OFFICE_PROFILE = "office.profile"; public static final String PARAMETER_FILEUPLOAD_FILE_SIZE_MAX = "fileupload.fileSizeMax"; private final Logger logger = Logger.getLogger(getClass().getName()); private static final String KEY = WebappContext.class.getName(); private final ServletFileUpload fileUpload; private final OfficeManager officeManager; private final OfficeDocumentConverter documentConverter; public WebappContext(ServletContext servletContext) { DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(); String fileSizeMax = servletContext.getInitParameter(PARAMETER_FILEUPLOAD_FILE_SIZE_MAX); fileUpload = new ServletFileUpload(fileItemFactory); if (fileSizeMax != null) { fileUpload.setFileSizeMax(Integer.parseInt(fileSizeMax)); logger.info("max file upload size set to " + fileSizeMax); } else { logger.warning("max file upload size not set"); } int officePort = 8100; String officePortParam = servletContext.getInitParameter(PARAMETER_OFFICE_PORT); if (officePortParam != null) { officePort = Integer.parseInt(officePortParam); } OfficeConnectionMode connectionMode = OfficeConnectionMode.socket(officePort); ManagedProcessOfficeManagerConfiguration configuration = new ManagedProcessOfficeManagerConfiguration(connectionMode); String officeHomeParam = servletContext.getInitParameter(PARAMETER_OFFICE_HOME); if (officeHomeParam != null) { configuration.setOfficeHome(new File(officeHomeParam)); } String officeProfileParam = servletContext.getInitParameter(PARAMETER_OFFICE_PROFILE); if (officeProfileParam != null) { configuration.setTemplateProfileDir(new File(officeProfileParam)); } officeManager = new ManagedProcessOfficeManager(configuration); documentConverter = new OfficeDocumentConverter(officeManager); } protected static void init(ServletContext servletContext) { WebappContext instance = new WebappContext(servletContext); servletContext.setAttribute(KEY, instance); instance.officeManager.start(); } protected static void destroy(ServletContext servletContext) { WebappContext instance = get(servletContext); instance.officeManager.stop(); } public static WebappContext get(ServletContext servletContext) { return (WebappContext) servletContext.getAttribute(KEY); } public ServletFileUpload getFileUpload() { return fileUpload; } public OfficeManager getOfficeManager() { return officeManager; } public OfficeDocumentConverter getDocumentConverter() { return documentConverter; } }
在web应用启动时初始化:
package org.artofsolving.jodconverter.sample.web; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class WebappContextListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { WebappContext.init(event.getServletContext()); } public void contextDestroyed(ServletContextEvent event) { WebappContext.destroy(event.getServletContext()); } }
转换servlet
package org.artofsolving.jodconverter.sample.web; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.artofsolving.jodconverter.DocumentFormat; import org.artofsolving.jodconverter.OfficeDocumentConverter; public class ConverterServlet extends HttpServlet { private static final long serialVersionUID = -591469426224201748L; private final Logger logger = Logger.getLogger(getClass().getName()); @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(request)) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "only multipart requests are allowed"); return; } WebappContext webappContext = WebappContext.get(getServletContext()); ServletFileUpload fileUpload = webappContext.getFileUpload(); OfficeDocumentConverter converter = webappContext .getDocumentConverter(); String outputExtension = FilenameUtils.getExtension(request .getRequestURI()); FileItem uploadedFile; try { uploadedFile = getUploadedFile(fileUpload, request); } catch (FileUploadException fileUploadException) { throw new ServletException(fileUploadException); } if (uploadedFile == null) { throw new NullPointerException("uploaded file is null"); } String inputExtension = FilenameUtils.getExtension(uploadedFile .getName()); String baseName = FilenameUtils.getBaseName(uploadedFile.getName()); File inputFile = File.createTempFile(baseName, "." + inputExtension); writeUploadedFile(uploadedFile, inputFile); File outputFile = File.createTempFile(baseName, "." + outputExtension); try { DocumentFormat outputFormat = converter.getFormatRegistry() .getFormatByExtension(outputExtension); long startTime = System.currentTimeMillis(); converter.convert(inputFile, outputFile); long conversionTime = System.currentTimeMillis() - startTime; logger.info(String.format( "successful conversion: %s [%db] to %s in %dms", inputExtension, inputFile.length(), outputExtension, conversionTime)); response.setContentType(outputFormat.getMediaType()); response.setHeader("Content-Disposition", "attachment; filename=" + baseName + "." + outputExtension); sendFile(outputFile, response); } catch (Exception exception) { logger.severe(String.format( "failed conversion: %s [%db] to %s; %s; input file: %s", inputExtension, inputFile.length(), outputExtension, exception, inputFile.getName())); throw new ServletException("conversion failed", exception); } finally { outputFile.delete(); inputFile.delete(); } } private void sendFile(File file, HttpServletResponse response) throws IOException { response.setContentLength((int) file.length()); InputStream inputStream = null; try { inputStream = new FileInputStream(file); IOUtils.copy(inputStream, response.getOutputStream()); } finally { IOUtils.closeQuietly(inputStream); } } private void writeUploadedFile(FileItem uploadedFile, File destinationFile) throws ServletException { try { uploadedFile.write(destinationFile); } catch (Exception exception) { throw new ServletException("error writing uploaded file", exception); } uploadedFile.delete(); } private FileItem getUploadedFile(ServletFileUpload fileUpload, HttpServletRequest request) throws FileUploadException { @SuppressWarnings("unchecked") List<FileItem> fileItems = fileUpload.parseRequest(request); for (FileItem fileItem : fileItems) { if (!fileItem.isFormField()) { return fileItem; } } return null; } }