├── pom.xml ├── readme.md └── src ├── main ├── java │ └── com │ │ └── yws │ │ └── demo │ │ └── word2pdf │ │ ├── WordService.java │ │ ├── WordToPdfDemoApplication.java │ │ └── impl │ │ ├── AsposeWordServiceImpl.java │ │ ├── LibreOfficeCommandWordServiceImpl.java │ │ └── LibreOfficeUnoWordServiceImpl.java └── resources │ ├── application.yml │ └── test.docx └── test └── java └── com └── yws └── demo └── word2pdf ├── WordServiceTests.java └── WordToPdfDemoApplicationTests.java /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.yws.demo 7 | word2pdf-demo 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | word2pdf-demo 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.1.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-actuator 36 | 37 | 38 | 39 | com.aspose 40 | aspose-words 41 | 18.6 42 | jdk16 43 | 44 | 45 | 46 | commons-io 47 | commons-io 48 | 2.4 49 | 50 | 51 | 52 | 53 | org.openoffice 54 | juh 55 | 4.1.2 56 | 57 | 58 | 59 | org.openoffice 60 | ridl 61 | 4.1.2 62 | 63 | 64 | 65 | org.openoffice 66 | jurt 67 | 4.1.2 68 | 69 | 70 | 71 | org.openoffice 72 | unoil 73 | 4.1.2 74 | 75 | 76 | 77 | org.openoffice 78 | bootstrap-connector 79 | 0.1.1 80 | 81 | 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-starter-test 86 | test 87 | 88 | 89 | 90 | 91 | 92 | 93 | org.springframework.boot 94 | spring-boot-maven-plugin 95 | 96 | 97 | 98 | 99 | 100 | 101 | AsposeJavaAPI 102 | Aspose Java API 103 | http://artifact.aspose.com/repo/ 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # WORD2PDF TOOL 2 | > 原本项目中使用了Microsoft Office来进行docx文件转换为pdf文件,但由于Microsoft Office是一款收费软件,且收费方式还是以人头计算的,在产品开发使用中存在版权问题。所以近日就收集网上的一些方案,并加以优化整合到了这个demo项目,进行对比,替换掉原本的方案。 3 | author : Felix Yan 4 | 5 | #### 方案一: Aspose库 6 | Aspose库是一款处理office文档都非常方便的库,支持多种语言,收费,支持免费试用(会在开头有红色版权标注) 7 | 8 | - [实现](https://github.com/yws179/word2pdf-demo/blob/master/src/main/java/com/yws/demo/word2pdf/impl/AsposeWordServiceImpl.java) 9 | - [运行](https://github.com/yws179/word2pdf-demo/blob/master/src/test/java/com/yws/demo/word2pdf/WordServiceTests.java) 10 | 11 | #### 方案二: 使用LibreOffice免费办公软件自带的soffice工具 12 | LibreOffice自带的soffice工具支持以命令的方式进行文件类型转换,所以本例子通过java执行命令来调用soffice完成word到pdf的转换 13 | 14 | - [实现](https://github.com/yws179/word2pdf-demo/blob/master/src/main/java/com/yws/demo/word2pdf/impl/LibreOfficeCommandWordServiceImpl.java) 15 | - [运行](https://github.com/yws179/word2pdf-demo/blob/master/src/test/java/com/yws/demo/word2pdf/WordServiceTests.java) 16 | 17 | #### 方案三:使用LibreOffice官网Api文档的方式(通过UNO) 18 | 19 | - [实现](https://github.com/yws179/word2pdf-demo/blob/master/src/main/java/com/yws/demo/word2pdf/impl/LibreOfficeUnoWordServiceImpl.java) 20 | - [运行](https://github.com/yws179/word2pdf-demo/blob/master/src/test/java/com/yws/demo/word2pdf/WordServiceTests.java) 21 | 22 | #### 方案四: 使用Jacob库(待实现)(仅支持windows) 23 | 此方法可通过调用 `Microsoft Office` / `WPS` 来实现转换 24 | 25 | 26 | ## Star History 27 | 28 | [![Star History Chart](https://api.star-history.com/svg?repos=yws179/word2pdf-tools&type=Date)](https://star-history.com/#yws179/word2pdf-tools&Date) 29 | -------------------------------------------------------------------------------- /src/main/java/com/yws/demo/word2pdf/WordService.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf; 2 | 3 | /** 4 | * @author Felix Yan 5 | * @data 2018/07/15 6 | */ 7 | public interface WordService { 8 | 9 | void word2pdf(String inPath, String outPath) throws Exception; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/yws/demo/word2pdf/WordToPdfDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WordToPdfDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(WordToPdfDemoApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/yws/demo/word2pdf/impl/AsposeWordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf.impl; 2 | 3 | import com.aspose.words.Document; 4 | import com.aspose.words.SaveFormat; 5 | import com.yws.demo.word2pdf.WordService; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * 通过aspose库转换 10 | * 11 | * @author Felix Yan 12 | * @data 2018/07/16 13 | */ 14 | @Service("asposeWordService") 15 | public class AsposeWordServiceImpl implements WordService { 16 | 17 | @Override 18 | public void word2pdf(String inPath, String outPath) throws Exception { 19 | Document doc = new Document(inPath); 20 | doc.save(outPath, SaveFormat.PDF); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/yws/demo/word2pdf/impl/LibreOfficeCommandWordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf.impl; 2 | 3 | import com.yws.demo.word2pdf.WordService; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.io.*; 10 | 11 | /** 12 | * 通过命令调用libreOffice的soffice工具转换 13 | * 14 | * @author Felix Yan 15 | * @data 2018/07/16 16 | */ 17 | @Service("commandWordService") 18 | public class LibreOfficeCommandWordServiceImpl implements WordService { 19 | 20 | private static final Logger logger = LoggerFactory.getLogger(LibreOfficeCommandWordServiceImpl.class); 21 | 22 | @Value("${soffice-dir:/usr/bin}") 23 | private String sofficeDir; 24 | 25 | @Override 26 | public void word2pdf(String inPath, String outPath) throws Exception { 27 | if (!new File(inPath).exists()) { 28 | throw new FileNotFoundException(); 29 | } 30 | String command = String.format("%s/soffice --convert-to pdf:writer_pdf_Export %s --outdir %s", sofficeDir, inPath, outPath); 31 | String output = this.executeCommand(command); 32 | logger.info("exec command:[{}]\noutput: [{}]", command, output); 33 | } 34 | 35 | protected String executeCommand(String command) throws IOException, InterruptedException { 36 | StringBuffer output = new StringBuffer(); 37 | Process p; 38 | p = Runtime.getRuntime().exec(command); 39 | p.waitFor(); 40 | try ( 41 | InputStreamReader inputStreamReader = new InputStreamReader(p.getInputStream(), "UTF-8"); 42 | BufferedReader reader = new BufferedReader(inputStreamReader) 43 | ) { 44 | String line = ""; 45 | while ((line = reader.readLine()) != null) { 46 | output.append(line + "\n"); 47 | } 48 | } 49 | p.destroy(); 50 | return output.toString(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/yws/demo/word2pdf/impl/LibreOfficeUnoWordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf.impl; 2 | 3 | import com.sun.star.beans.PropertyValue; 4 | import com.sun.star.frame.XComponentLoader; 5 | import com.sun.star.frame.XDesktop; 6 | import com.sun.star.frame.XStorable; 7 | import com.sun.star.lang.XComponent; 8 | import com.sun.star.lang.XMultiComponentFactory; 9 | import com.sun.star.uno.UnoRuntime; 10 | import com.sun.star.uno.XComponentContext; 11 | import com.yws.demo.word2pdf.WordService; 12 | import ooo.connector.BootstrapSocketConnector; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.stereotype.Service; 15 | 16 | /** 17 | * @author Felix Yan 18 | * @data 2018/07/19 19 | */ 20 | @Service("unoWordService") 21 | public class LibreOfficeUnoWordServiceImpl implements WordService { 22 | 23 | @Value("${soffice-dir:/usr/bin}") 24 | private String sofficeDir; 25 | 26 | @Override 27 | public void word2pdf(String inPath, String outPath) throws Exception { 28 | 29 | if (!outPath.endsWith(".pdf")) { 30 | outPath += "_result.pdf"; 31 | } 32 | 33 | XComponentContext xContext = BootstrapSocketConnector.bootstrap(sofficeDir); 34 | 35 | XMultiComponentFactory xMCF = xContext.getServiceManager(); 36 | 37 | Object oDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", xContext); 38 | 39 | XDesktop xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop); 40 | 41 | XComponentLoader xCompLoader = UnoRuntime.queryInterface(XComponentLoader.class, xDesktop); 42 | 43 | XComponent xComp = xCompLoader.loadComponentFromURL( 44 | "file:///" + inPath, "_blank", 0, new PropertyValue[0]); 45 | 46 | XStorable xStorable = UnoRuntime.queryInterface(XStorable.class, xComp); 47 | 48 | PropertyValue[] propertyValue = new PropertyValue[2]; 49 | propertyValue[0] = new PropertyValue(); 50 | propertyValue[0].Name = "Overwrite"; 51 | propertyValue[0].Value = Boolean.TRUE; 52 | propertyValue[1] = new PropertyValue(); 53 | propertyValue[1].Name = "FilterName"; 54 | propertyValue[1].Value = "writer_pdf_Export"; 55 | xStorable.storeToURL("file:///" + outPath, propertyValue); 56 | 57 | xDesktop.terminate(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yws179/word2pdf-tools/c8dbeae631de44f198930aa6046463b618ec5c22/src/main/resources/application.yml -------------------------------------------------------------------------------- /src/main/resources/test.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yws179/word2pdf-tools/c8dbeae631de44f198930aa6046463b618ec5c22/src/main/resources/test.docx -------------------------------------------------------------------------------- /src/test/java/com/yws/demo/word2pdf/WordServiceTests.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | import org.springframework.util.ResourceUtils; 8 | 9 | import javax.annotation.Resource; 10 | import java.io.File; 11 | 12 | /** 13 | * @author Felix Yan 14 | * @data 2018/07/16 15 | */ 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | public class WordServiceTests { 19 | 20 | @Resource 21 | private WordService commandWordService; 22 | 23 | @Resource 24 | private WordService asposeWordService; 25 | 26 | @Resource 27 | private WordService unoWordService; 28 | 29 | @Test 30 | public void testAsposeWord2Pdf() throws Exception { 31 | test(asposeWordService); 32 | } 33 | 34 | @Test 35 | public void testLibreOfficeCommandWord2Pdf() throws Exception { 36 | test(commandWordService); 37 | } 38 | 39 | @Test 40 | public void testLibreOfficeUnoWord2Pdf() throws Exception { 41 | test(unoWordService); 42 | } 43 | 44 | public void test(WordService wordService) throws Exception { 45 | File file = ResourceUtils.getFile("classpath:test.docx"); 46 | File outFile = new File("./test.pdf"); 47 | wordService.word2pdf(file.getAbsolutePath(), outFile.getAbsolutePath()); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/yws/demo/word2pdf/WordToPdfDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.yws.demo.word2pdf; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class WordToPdfDemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | // @Test 17 | // public void word2pdf() throws FileNotFoundException { 18 | // String LibreOffice_HOME = "/usr/lib/libreoffice/program"; 19 | // File file = ResourceUtils.getFile("classpath:dsi_fonts_test.docx"); 20 | // 21 | // DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration(); 22 | // configuration.setOfficeHome(new File(LibreOffice_HOME)); 23 | // configuration.setPortNumber(8100); 24 | // configuration.setTaskExecutionTimeout(1000 * 60 * 25L); 25 | // configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L); 26 | // OfficeManager officeManager = configuration.buildOfficeManager(); 27 | // officeManager.start(); 28 | // OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager); 29 | // converter.getFormatRegistry(); 30 | // try { 31 | // converter.convert(file, new File("./target.pdf")); 32 | // } catch (Exception e) { 33 | // e.printStackTrace(); 34 | // } finally { 35 | // officeManager.stop(); 36 | // } 37 | // } 38 | 39 | } 40 | --------------------------------------------------------------------------------