初次提交
This commit is contained in:
10
README.md
10
README.md
@@ -1,9 +1,9 @@
|
|||||||
# document
|
# document
|
||||||
|
|
||||||
文书服务
|
文书服务
|
||||||
|
|
||||||
api下为调用的接口
|
api下为调用的接口,在需要处理文书的项目中引用,以`fegin方式`配置Service后进行调用
|
||||||
|
|
||||||
server下为使用jacob处理word文书,使用openoffice来进行pdf转换
|
server下为使用jacob处理word文书,使用openoffice来进行pdf转换,`java -jar xxx.jar`启动
|
||||||
|
|
||||||
tl-server下仅进行word转pdf,使用的docto调用office来转换
|
tl-server下仅进行word转pdf,使用的docto调用office来转换,`java -jar xxx.jar`启动
|
||||||
33
api/pom.xml
Normal file
33
api/pom.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<name>document api</name>
|
||||||
|
<description>文档操作api</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.20</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.optima.document.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档接口
|
||||||
|
* @author Elias
|
||||||
|
* @date 2021-09-28 16:00
|
||||||
|
*/
|
||||||
|
public interface DocumentService {
|
||||||
|
/**
|
||||||
|
* generate word
|
||||||
|
* @param templateData word模版流
|
||||||
|
* @param dataModel 数据模型
|
||||||
|
* @return 修改后的文档流
|
||||||
|
*/
|
||||||
|
default byte[] generateWord(byte[] templateData, Map<String, Object> dataModel) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word to pdf
|
||||||
|
* @param templateData word模版流
|
||||||
|
* @param clear 是否清除占位符
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default byte[] wordToPdf(byte[] templateData, boolean clear) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word to image
|
||||||
|
* @param templateData word模版流
|
||||||
|
* @param targetFormat 目标格式 支持jpeg, jpg, gif, tiff or png
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default byte[] wordToImage(byte[] templateData, String targetFormat) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param source 文档
|
||||||
|
* @param toFindText 需要替换的文本
|
||||||
|
* @param imgSource 图片
|
||||||
|
* @param width 宽度
|
||||||
|
* @param height 高度
|
||||||
|
* @return 修改后的文档
|
||||||
|
*/
|
||||||
|
default byte[] insertJpeg(byte[] source, String toFindText, byte[] imgSource, int width, int height){
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @param toFindText
|
||||||
|
* @param imgSource
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default byte[] insertJpeg(byte[] source, String toFindText, List<byte[]> imgSource, int width, int height) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
default byte[] fieldToWord(byte[] source, Map<String, Object> infoMap) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
17
pom.xml
Normal file
17
pom.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<name>document</name>
|
||||||
|
<description>文档操作模块</description>
|
||||||
|
<modules>
|
||||||
|
<module>api</module>
|
||||||
|
<module>server</module>
|
||||||
|
<module>tl-server</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
</project>
|
||||||
135
server/pom.xml
Normal file
135
server/pom.xml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document-server</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>document server</name>
|
||||||
|
<description>文档操作服务</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- jacob -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.jacob-project</groupId>
|
||||||
|
<artifactId>jacob</artifactId>
|
||||||
|
<version>1.18</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${basedir}/src/main/resources/libs/jacob.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.artofsolving</groupId>
|
||||||
|
<artifactId>jodconverter</artifactId>
|
||||||
|
<version>2.2.2</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${basedir}/src/main/resources/libs/jodconverter-2.2.2.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
<!-- poi2 依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>apache</groupId>
|
||||||
|
<artifactId>poi2</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${basedir}/src/main/resources/libs/poi2-1.0.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
<!-- poi依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
<version>3.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>3.14</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-scratchpad</artifactId>
|
||||||
|
<version>3.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>joda-time</groupId>
|
||||||
|
<artifactId>joda-time</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.20</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jodconverter</groupId>
|
||||||
|
<artifactId>jodconverter-core</artifactId>
|
||||||
|
<version>4.0.0-RELEASE</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
|
<artifactId>pdfbox-tools</artifactId>
|
||||||
|
<version>2.0.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includeSystemScope>true</includeSystemScope>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.optima.document.server;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class DocumentServer {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DocumentServer.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.optima.document.server.api;
|
||||||
|
|
||||||
|
import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
|
||||||
|
import com.artofsolving.jodconverter.DocumentConverter;
|
||||||
|
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
|
||||||
|
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
|
||||||
|
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
|
||||||
|
import com.optima.document.api.DocumentService;
|
||||||
|
import com.optima.document.server.utils.DocToPdfUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.rendering.ImageType;
|
||||||
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务接口实现
|
||||||
|
* @author Elias
|
||||||
|
* @date 2021-09-28 16:18
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class DocumentServiceImpl implements DocumentService {
|
||||||
|
|
||||||
|
public byte[] fieldToWord(byte[] source, Map<String, Object> infoMap) {
|
||||||
|
return DocToPdfUtil.fieldToWord(source, infoMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] insertJpeg(byte[] source, String toFindText, byte[] imgSource, int width, int height) {
|
||||||
|
return DocToPdfUtil.insertJpeg(source, toFindText, imgSource, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] insertJpeg(byte[] source, String toFindText, List<byte[]> imgSource, int width, int height) {
|
||||||
|
return DocToPdfUtil.insertJpeg(source, toFindText, imgSource, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] wordToPdf(byte[] source, String sourceFormat, boolean clear) {
|
||||||
|
try {
|
||||||
|
if (clear) {
|
||||||
|
source = DocToPdfUtil.clearPlaceholder(source);
|
||||||
|
}
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
String command = "D:\\OpenOffice4\\program\\soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";
|
||||||
|
Process p = Runtime.getRuntime().exec(command);
|
||||||
|
OpenOfficeConnection connection = new SocketOpenOfficeConnection();
|
||||||
|
connection.connect();
|
||||||
|
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DefaultDocumentFormatRegistry formatRegistry = new DefaultDocumentFormatRegistry();
|
||||||
|
converter.convert(new ByteArrayInputStream(source), formatRegistry.getFormatByFileExtension(sourceFormat), bos, formatRegistry.getFormatByFileExtension("pdf"));
|
||||||
|
connection.disconnect();
|
||||||
|
p.destroy();
|
||||||
|
log.info("word to pdf=======consuming:{} milliseconds", System.currentTimeMillis() - t1);
|
||||||
|
return bos.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] wordToImage(byte[] source, String sourceFormat, String targetFormat) {
|
||||||
|
try {
|
||||||
|
byte[] pdfBytes = wordToPdf(source, sourceFormat, true);
|
||||||
|
PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes));
|
||||||
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
|
BufferedImage bim = pdfRenderer.renderImageWithDPI(
|
||||||
|
0, 300, ImageType.RGB);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ImageIOUtil.writeImage(bim, targetFormat, bos, 300);
|
||||||
|
document.close();
|
||||||
|
return bos.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.optima.document.server.config;
|
||||||
|
|
||||||
|
import com.optima.document.api.DocumentService;
|
||||||
|
import com.optima.document.server.api.DocumentServiceImpl;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端配置
|
||||||
|
* @author Elias
|
||||||
|
* @date 2021-09-28 16:12
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "document")
|
||||||
|
@Data
|
||||||
|
public class DocumentConfig {
|
||||||
|
|
||||||
|
private String tempDir;
|
||||||
|
|
||||||
|
private String openOfficeHome;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档接口
|
||||||
|
* @return httpinvoker
|
||||||
|
*/
|
||||||
|
@Bean(name = "/document-service")
|
||||||
|
HttpInvokerServiceExporter wordService() {
|
||||||
|
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
|
||||||
|
exporter.setService( new DocumentServiceImpl() );
|
||||||
|
exporter.setServiceInterface(DocumentService.class);
|
||||||
|
return exporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,493 @@
|
|||||||
|
package com.optima.document.server.utils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by xianjun on 2016/6/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转型操作工具类
|
||||||
|
*/
|
||||||
|
public final class CastUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为String 型 默认为空
|
||||||
|
*/
|
||||||
|
public static String castString(Object obj) {
|
||||||
|
return CastUtil.castString(obj, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为String 型(提供默认值)
|
||||||
|
*/
|
||||||
|
public static String castString(Object obj, String defaultValue) {
|
||||||
|
return obj != null ? String.valueOf(obj) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为double型 默认为0
|
||||||
|
*/
|
||||||
|
public static double castDouble(Object obj) {
|
||||||
|
return CastUtil.castDouble(obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为double型(提供默认值)
|
||||||
|
*/
|
||||||
|
public static double castDouble(Object obj, double defaultValue) {
|
||||||
|
double doubleValue = defaultValue;
|
||||||
|
if (obj != null) {
|
||||||
|
String strValue = castString(obj);
|
||||||
|
if (StringUtils.isNotEmpty(strValue)) {
|
||||||
|
try {
|
||||||
|
doubleValue = Double.parseDouble(strValue);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
doubleValue = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为long型,默认值为0
|
||||||
|
*/
|
||||||
|
public static long castLong(Object obj) {
|
||||||
|
return CastUtil.castLong(obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为long型(提供默认值)
|
||||||
|
*/
|
||||||
|
public static long castLong(Object obj, long defaultValue) {
|
||||||
|
long longValue = defaultValue;
|
||||||
|
if (obj != null) {
|
||||||
|
String strValue = castString(obj);
|
||||||
|
if (!StringUtils.isEmpty(strValue)) {
|
||||||
|
try {
|
||||||
|
longValue = Long.parseLong(strValue);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
longValue = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return longValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为int型 默认值为0
|
||||||
|
*/
|
||||||
|
public static int castInt(Object obj) {
|
||||||
|
return CastUtil.castInt(obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为int型(提供默认值)
|
||||||
|
*/
|
||||||
|
public static int castInt(Object obj, int defaultValue) {
|
||||||
|
int intValue = defaultValue;
|
||||||
|
if (obj != null) {
|
||||||
|
String strValue = castString(obj);
|
||||||
|
if (StringUtils.isNotEmpty(strValue)) {
|
||||||
|
try {
|
||||||
|
intValue = Integer.parseInt(strValue);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
intValue = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return intValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为double型,默认值为false
|
||||||
|
*/
|
||||||
|
public static boolean castBoolean(Object obj) {
|
||||||
|
return CastUtil.castBoolean(obj, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为double型,提供默认值
|
||||||
|
*/
|
||||||
|
public static boolean castBoolean(Object obj, boolean defaultValue) {
|
||||||
|
boolean booleanValue = defaultValue;
|
||||||
|
if (obj != null) {
|
||||||
|
booleanValue = Boolean.parseBoolean(castString(obj));
|
||||||
|
}
|
||||||
|
return booleanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转时间戳为date类型
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Date castDate(long time, Date defaultValue) {
|
||||||
|
Date dateValue = defaultValue;
|
||||||
|
if (time != 0) {
|
||||||
|
DateTime dateTime = new DateTime(time);
|
||||||
|
dateValue = dateTime.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date castDateNo(long time) {
|
||||||
|
return castDate(time, new Date(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转时间戳为date类型
|
||||||
|
*/
|
||||||
|
public static Date castDate(long time) {
|
||||||
|
return castDate(time, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取开始时间
|
||||||
|
*
|
||||||
|
* @Title: getStartTime
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param date
|
||||||
|
* @param monthTime
|
||||||
|
* @param dateTime
|
||||||
|
* @param hour
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static Date getStartTime(Date date, int monthTime, int dateTime, int hour) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.set(CastUtil.castInt(CastUtil.castStringByDate(date, "yyyy")), date.getMonth() + monthTime, date.getDate() + dateTime, 0 + hour, 0, 0);
|
||||||
|
return calendar.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取结束时间
|
||||||
|
*
|
||||||
|
* @Title: getEndTime
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param date
|
||||||
|
* @param monthTime
|
||||||
|
* @param dateTime
|
||||||
|
* @param hour
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static Date getEndTime(Date date, int monthTime, int dateTime, int hour) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.set(CastUtil.castInt(CastUtil.castStringByDate(date, "yyyy")), date.getMonth() + monthTime, date.getDate() + dateTime, 23 + hour, 59, 59);
|
||||||
|
return calendar.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转日期格式为字符串
|
||||||
|
*/
|
||||||
|
public static String castStringDate(Date date, Date defaultValue) {
|
||||||
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Date dateValue = defaultValue;
|
||||||
|
String dateString = "";
|
||||||
|
if (date != null) {
|
||||||
|
dateString = fmt.format(date);
|
||||||
|
} else {
|
||||||
|
dateString = fmt.format(dateValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换日期格式为年-月-日
|
||||||
|
* @Title: castStringIntegerDate
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param date
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String castStringIntegerDate(Date date) {
|
||||||
|
return castStringIntegerDate(date, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换格式为年-月-日
|
||||||
|
* @Title: castStringIntegerDate
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param date
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String castStringIntegerDate(Date date, Date defaultValue) {
|
||||||
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date dateValue = defaultValue;
|
||||||
|
String dateString = "";
|
||||||
|
if (date != null) {
|
||||||
|
dateString = fmt.format(date);
|
||||||
|
} else {
|
||||||
|
dateString = fmt.format(dateValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据传入的格式,转换为不同的日期
|
||||||
|
*
|
||||||
|
* @Title: castStringByDate
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param date
|
||||||
|
* @param pattern
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String castStringByDate(Date date, String pattern) {
|
||||||
|
SimpleDateFormat fmt = new SimpleDateFormat(pattern);
|
||||||
|
Date dateValue = new Date();
|
||||||
|
String dateString = "";
|
||||||
|
if (date != null) {
|
||||||
|
dateString = fmt.format(date);
|
||||||
|
} else {
|
||||||
|
dateString = fmt.format(dateValue);
|
||||||
|
}
|
||||||
|
return dateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转日期格式为字符串
|
||||||
|
*/
|
||||||
|
public static String castStringDate(Date date) {
|
||||||
|
return castStringDate(date, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转 字符串为日期格式
|
||||||
|
*/
|
||||||
|
public static Date castDateByString(String defaultDate){
|
||||||
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
try {
|
||||||
|
Date date = fmt.parse(defaultDate);
|
||||||
|
return date;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转BigDecimal为字符串
|
||||||
|
*/
|
||||||
|
public static String castStringByDecimal(BigDecimal value, String pattern) {
|
||||||
|
DecimalFormat fmt = new DecimalFormat(pattern);
|
||||||
|
try {
|
||||||
|
String tempValue = fmt.format(value.stripTrailingZeros());
|
||||||
|
return tempValue;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO: handle exception
|
||||||
|
e.printStackTrace();
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换字符串,判断是否非空
|
||||||
|
* @Title: castStringByString
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param defaultString
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String castStringByString(String defaultString) {
|
||||||
|
String value = defaultString == null ? "" : defaultString;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去除html标签
|
||||||
|
* @Title: delHTMLTag
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param htmlStr
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String delHTMLTag(String htmlStr){
|
||||||
|
String regEx_script="<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
|
||||||
|
String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
|
||||||
|
String regEx_html="<[^>]+>"; //定义HTML标签的正则表达式
|
||||||
|
|
||||||
|
Pattern p_script=Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_script=p_script.matcher(htmlStr);
|
||||||
|
htmlStr=m_script.replaceAll(""); //过滤script标签
|
||||||
|
|
||||||
|
Pattern p_style=Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_style=p_style.matcher(htmlStr);
|
||||||
|
htmlStr=m_style.replaceAll(""); //过滤style标签
|
||||||
|
|
||||||
|
Pattern p_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_html=p_html.matcher(htmlStr);
|
||||||
|
htmlStr=m_html.replaceAll(""); //过滤html标签
|
||||||
|
|
||||||
|
return htmlStr.trim(); //返回文本字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过身份证号码获取出生日期、性别、年龄
|
||||||
|
* @author xianjun
|
||||||
|
* @param certificateNo
|
||||||
|
* @return 返回的出生日期格式:1990-01-01 性别格式:F-女,M-男
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getBirAgeSex(String certificateNo) {
|
||||||
|
String birthday = "";
|
||||||
|
String age = "";
|
||||||
|
String sexCode = "";
|
||||||
|
|
||||||
|
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
char[] number = certificateNo.toCharArray();
|
||||||
|
boolean flag = true;
|
||||||
|
if (number.length == 15) {
|
||||||
|
for (int x = 0; x < number.length; x++) {
|
||||||
|
if (!flag) return new HashMap<String, String>();
|
||||||
|
flag = Character.isDigit(number[x]);
|
||||||
|
}
|
||||||
|
} else if (number.length == 18) {
|
||||||
|
for (int x = 0; x < number.length - 1; x++) {
|
||||||
|
if (!flag) return new HashMap<String, String>();
|
||||||
|
flag = Character.isDigit(number[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag && certificateNo.length() == 15) {
|
||||||
|
birthday = "19" + certificateNo.substring(6, 8) + "-"
|
||||||
|
+ certificateNo.substring(8, 10) + "-"
|
||||||
|
+ certificateNo.substring(10, 12);
|
||||||
|
sexCode = Integer.parseInt(certificateNo.substring(certificateNo.length() - 3, certificateNo.length())) % 2 == 0 ? "F" : "M";
|
||||||
|
age = (year - Integer.parseInt("19" + certificateNo.substring(6, 8))) + "";
|
||||||
|
} else if (flag && certificateNo.length() == 18) {
|
||||||
|
birthday = certificateNo.substring(6, 10) + "-"
|
||||||
|
+ certificateNo.substring(10, 12) + "-"
|
||||||
|
+ certificateNo.substring(12, 14);
|
||||||
|
sexCode = Integer.parseInt(certificateNo.substring(certificateNo.length() - 4, certificateNo.length() - 1)) % 2 == 0 ? "F" : "M";
|
||||||
|
age = (year - Integer.parseInt(certificateNo.substring(6, 10))) + "";
|
||||||
|
}
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
map.put("birthday", birthday);
|
||||||
|
map.put("age", age);
|
||||||
|
map.put("sexCode", sexCode);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 将Date类型的时间转为long类型的时间戳
|
||||||
|
* @Author SuXingYong
|
||||||
|
* @Date 2020/1/10 10:40
|
||||||
|
* @Param [date]
|
||||||
|
* @Return long
|
||||||
|
**/
|
||||||
|
public static long castDateForLong(Date date){
|
||||||
|
long result = 0;
|
||||||
|
if (date != null){
|
||||||
|
result = date.getTime();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 将 yyyy-MM-dd HH:mm:ss 类型的时间字符串转换为long类型的时间戳
|
||||||
|
* @Author SuXingYong
|
||||||
|
* @Date 2020/1/10 10:46
|
||||||
|
* @Param [dateStr]
|
||||||
|
* @Return long
|
||||||
|
**/
|
||||||
|
public static long castDateStrForLong(String dateStr){
|
||||||
|
long result = 0;
|
||||||
|
Date date = CastUtil.castDateByString(dateStr);
|
||||||
|
if (date != null){
|
||||||
|
result = date.getTime();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 将java.sql.Timestamp转化为对应格式的String
|
||||||
|
* @Author SuXingYong
|
||||||
|
* @Date 2020/3/10 15:13
|
||||||
|
* @Param [time, strFormat]
|
||||||
|
* @Return java.lang.String
|
||||||
|
**/
|
||||||
|
public static String castTimestampForString(java.sql.Timestamp time, String strFormat) {
|
||||||
|
DateFormat df = new SimpleDateFormat(strFormat);
|
||||||
|
String str = df.format(time);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某年某月的第一天
|
||||||
|
* @author xianjun
|
||||||
|
* @param year
|
||||||
|
* @param month
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getFirstDayByMonth(int year, int month) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
// 设置年份
|
||||||
|
cal.set(Calendar.YEAR,year);
|
||||||
|
// 设置月份
|
||||||
|
cal.set(Calendar.MONTH, month-1);
|
||||||
|
// 获取某月最小天数
|
||||||
|
int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
|
||||||
|
// 设置最小天数
|
||||||
|
cal.set(Calendar.DAY_OF_MONTH, firstDay);
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
// 格式化
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String firstDayOfMonth = sdf.format(cal.getTime());
|
||||||
|
return firstDayOfMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某年某月的最后一天
|
||||||
|
*
|
||||||
|
* @author xianjun
|
||||||
|
* @param year
|
||||||
|
* @param month
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getLastDayByMonth(int year, int month) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
// 设置年份
|
||||||
|
cal.set(Calendar.YEAR, year);
|
||||||
|
// 设置月份
|
||||||
|
cal.set(Calendar.MONTH, month-1);
|
||||||
|
// 获取某月最大天数
|
||||||
|
int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||||
|
// 设置日历中月份的最大天数
|
||||||
|
cal.set(Calendar.DAY_OF_MONTH, lastDay);
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
|
// 格式化时间
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String lastDayOfMonth = sdf.format(cal.getTime());
|
||||||
|
return lastDayOfMonth;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,792 @@
|
|||||||
|
package com.optima.document.server.utils;
|
||||||
|
|
||||||
|
import com.jacob.activeX.ActiveXComponent;
|
||||||
|
import com.jacob.com.ComThread;
|
||||||
|
import com.jacob.com.Dispatch;
|
||||||
|
import com.jacob.com.Variant;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xianjun
|
||||||
|
* @version 2017年4月20日 上午10:48:46 word转pdf工具类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class DocToPdfUtil {
|
||||||
|
|
||||||
|
private static final int wdFormatPDF = 17; // pdf格式
|
||||||
|
private static final int xlTypePDF = 0;
|
||||||
|
private static final int ppSaveAsPDF = 32;
|
||||||
|
// 代表一个word 程序
|
||||||
|
private static ActiveXComponent MsWordApp = null;
|
||||||
|
// 代表进行处理的word 文档
|
||||||
|
private static Dispatch document = null;
|
||||||
|
// word文档
|
||||||
|
private Dispatch doc;
|
||||||
|
// word运行程序
|
||||||
|
private ActiveXComponent word;
|
||||||
|
// 所有word文档集合
|
||||||
|
private Dispatch documents;
|
||||||
|
// 选定的范围和插入点
|
||||||
|
private Dispatch selection;
|
||||||
|
|
||||||
|
private boolean saveOnExit = true;
|
||||||
|
|
||||||
|
public DocToPdfUtil() throws Exception {
|
||||||
|
ComThread.InitSTA();
|
||||||
|
if (word == null) {
|
||||||
|
word = new ActiveXComponent("Word.Application");
|
||||||
|
// 不可见打开word
|
||||||
|
word.setProperty("Visible", new Variant(false));
|
||||||
|
// 禁用宏
|
||||||
|
word.setProperty("AutomationSecurity", new Variant(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (documents == null)
|
||||||
|
documents = word.getProperty("Documents").toDispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置退出时参数
|
||||||
|
*
|
||||||
|
* @Title: setSaveOnExit
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param saveOnExit true-退出时保存文件,false-退出时不保存文件
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void setSaveOnExit(boolean saveOnExit) {
|
||||||
|
this.saveOnExit = saveOnExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开一个已存在的文档
|
||||||
|
*
|
||||||
|
* @Title: openDocument
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param docPath
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void openDocument(String docPath) {
|
||||||
|
closeDocument();
|
||||||
|
doc = Dispatch.call(documents, "Open", docPath).toDispatch();
|
||||||
|
selection = Dispatch.get(word, "Selection").toDispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件保存或另存为路径
|
||||||
|
*
|
||||||
|
* @Title: save
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param savePath
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void save(String savePath) {
|
||||||
|
Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(), "FileSaveAs", savePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭文档
|
||||||
|
* @Title: closeDocument
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param val 0不保存修改 -1 保存修改 -2 提示是否保存修改
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void closeDocument(int val) {
|
||||||
|
Dispatch.call(doc, "Close", new Variant(val));
|
||||||
|
doc = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭当前word文档
|
||||||
|
*
|
||||||
|
* @Title: cloaseDocument
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void cloaseDocument() {
|
||||||
|
if (doc != null) {
|
||||||
|
Dispatch.call(doc, "Save");
|
||||||
|
Dispatch.call(doc, "Close", new Variant(saveOnExit));
|
||||||
|
doc = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭全部应用
|
||||||
|
*
|
||||||
|
* @Title: close
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public void close() {
|
||||||
|
if (word != null) {
|
||||||
|
//Dispatch.call(word, "Quit");
|
||||||
|
word.invoke("Quit",0);
|
||||||
|
word = null;
|
||||||
|
}
|
||||||
|
selection = null;
|
||||||
|
documents = null;
|
||||||
|
ComThread.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word转pdf
|
||||||
|
*
|
||||||
|
* @author xianjun
|
||||||
|
* @version 2017年4月20日 上午9:56:09
|
||||||
|
* @describe
|
||||||
|
* @param fromAddress
|
||||||
|
* 待转地址
|
||||||
|
* toAddress 新文件地址
|
||||||
|
*/
|
||||||
|
// public static String wordToPdf(String fromAddress) {
|
||||||
|
// //ActiveXComponent ax = null;
|
||||||
|
// String toAddress = splitSuffx(fromAddress);
|
||||||
|
// try {
|
||||||
|
// PoiWordUtil.wordToPdf(fromAddress,toAddress);
|
||||||
|
// return toAddress;
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*try {
|
||||||
|
// long startTime = System.currentTimeMillis();
|
||||||
|
//
|
||||||
|
// *//**
|
||||||
|
// * 创建不同的控件调用不同的值 Word-Word.Application Excel-Excel.Application
|
||||||
|
// * Powerpoint-Powerpoint.Application Outlook-Outlook.Application
|
||||||
|
// *//*
|
||||||
|
// ax = new ActiveXComponent("Word.Application");
|
||||||
|
// *//**
|
||||||
|
// * 设置打开文件不可见
|
||||||
|
// *//*
|
||||||
|
// ax.setProperty("Visible", false);
|
||||||
|
// *//**
|
||||||
|
// * 获取word文档中所有内容
|
||||||
|
// *//*
|
||||||
|
// Dispatch docs = ax.getProperty("Documents").toDispatch();
|
||||||
|
// *//**
|
||||||
|
// * 打开word文档,并设置word为不可编辑和不需确认
|
||||||
|
// *//*
|
||||||
|
// Dispatch doc = Dispatch.call(docs, "Open", fromAddress, false, true).toDispatch();
|
||||||
|
// File tofile = new File(toAddress);
|
||||||
|
// if (tofile.exists()) {
|
||||||
|
// tofile.delete();
|
||||||
|
// }
|
||||||
|
// // word文件另存为pdf文件
|
||||||
|
// Dispatch.call(doc, "SaveAs", toAddress, wdFormatPDF);
|
||||||
|
// // 关闭word文档
|
||||||
|
// Dispatch.call(doc, "Close", false);
|
||||||
|
// long endTime = System.currentTimeMillis();
|
||||||
|
// System.out.println("转换完成,总共耗时" + (endTime - startTime));
|
||||||
|
// return toAddress;
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// System.out.println("=============Error:文档转换失败:" + e.getMessage());
|
||||||
|
// return null;
|
||||||
|
// } */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static String wordToPdf(String fromAddress, String fileName) throws Exception{
|
||||||
|
// String fileRootPath = UploadFileUtils.getPath("write");
|
||||||
|
// String dateUrl = CastUtil.castStringByDate(new Date(), "yyyy-MM-dd");
|
||||||
|
// String htmlFileDirPath = File.separator + dateUrl;
|
||||||
|
// File htmlDirFile = new File(fileRootPath + htmlFileDirPath);
|
||||||
|
// if (!htmlDirFile.exists()) {
|
||||||
|
// htmlDirFile.mkdirs();
|
||||||
|
// }
|
||||||
|
// //html文件路径
|
||||||
|
// String pdfFilePath = htmlDirFile.getPath() + File.separator + fileName + "." + "pdf";
|
||||||
|
// long startTime = System.currentTimeMillis();
|
||||||
|
// File tofile = new File(pdfFilePath);
|
||||||
|
// if (tofile.exists()) {
|
||||||
|
// tofile.delete();
|
||||||
|
// }
|
||||||
|
// // word文件另存为pdf文件
|
||||||
|
// PoiWordUtil.wordToPdf(fromAddress,pdfFilePath);
|
||||||
|
// // 关闭word文档
|
||||||
|
// long endTime = System.currentTimeMillis();
|
||||||
|
// System.out.println("转换完成,总共耗时" + (endTime - startTime));
|
||||||
|
// return "/"+dateUrl + "/" + fileName + "." + "pdf";
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static String excel2PDF(String fromAddress){
|
||||||
|
String toAddress = splitSuffx(fromAddress);
|
||||||
|
try{
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
ActiveXComponent app = new ActiveXComponent("Excel.Application");
|
||||||
|
app.setProperty("Visible", false);
|
||||||
|
Dispatch excels = app.getProperty("Workbooks").toDispatch();
|
||||||
|
Dispatch excel = Dispatch.call(excels,"Open",fromAddress,false,true).toDispatch();
|
||||||
|
File tofile = new File(toAddress);
|
||||||
|
if (tofile.exists()) {
|
||||||
|
tofile.delete();
|
||||||
|
}
|
||||||
|
Dispatch.call(excel,"ExportAsFixedFormat",xlTypePDF,toAddress);
|
||||||
|
Dispatch.call(excel, "Close",false);
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("转换完成,总共耗时" + (endTime - startTime));
|
||||||
|
return toAddress;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("=============Error:文档转换失败:" + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static String ppt2PDF(String fromAddress){
|
||||||
|
String toAddress = splitSuffx(fromAddress);
|
||||||
|
try{
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
ActiveXComponent app = new ActiveXComponent("PowerPoint.Application");
|
||||||
|
//app.setProperty("Visible", msofalse);
|
||||||
|
Dispatch ppts = app.getProperty("Presentations").toDispatch();
|
||||||
|
|
||||||
|
Dispatch ppt = Dispatch.call(ppts,
|
||||||
|
"Open",
|
||||||
|
fromAddress,
|
||||||
|
true,//ReadOnly
|
||||||
|
true,//Untitled指定文件是否有标题
|
||||||
|
false//WithWindow指定文件是否可见
|
||||||
|
).toDispatch();
|
||||||
|
|
||||||
|
Dispatch.call(ppt,
|
||||||
|
"SaveAs",
|
||||||
|
toAddress,
|
||||||
|
ppSaveAsPDF
|
||||||
|
);
|
||||||
|
|
||||||
|
Dispatch.call(ppt, "Close");
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("转换完成,总共耗时" + (endTime - startTime));
|
||||||
|
return toAddress;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("=============Error:文档转换失败:" + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径处理函数,提取路径后缀
|
||||||
|
*
|
||||||
|
* @author xianjun
|
||||||
|
* @version 2017年4月20日 上午10:54:49
|
||||||
|
* @describe
|
||||||
|
* @param fromAddress
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String splitSuffx(String fromAddress) {
|
||||||
|
String toAddress = fromAddress.substring(0, fromAddress.lastIndexOf(".") + 1);
|
||||||
|
toAddress = toAddress + "pdf";
|
||||||
|
return toAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从选定内容或插入点开始查找文本
|
||||||
|
*
|
||||||
|
* @param toFindText
|
||||||
|
* 要查找的文本
|
||||||
|
* @return boolean true-查找到并选中该文本,false-未查找到文本
|
||||||
|
*/
|
||||||
|
public static boolean find(ActiveXComponent ax,String toFindText) {
|
||||||
|
if (toFindText == null || toFindText.equals(""))
|
||||||
|
return false;
|
||||||
|
Dispatch selection = Dispatch.get(ax, "Selection").toDispatch(); // 输入内容需要的对象
|
||||||
|
// 从selection所在位置开始查询
|
||||||
|
Dispatch find1 = Dispatch.call(selection, "Find").toDispatch();
|
||||||
|
// 设置要查找的内容
|
||||||
|
Dispatch.put(find1, "Text", toFindText);
|
||||||
|
// 向前查找
|
||||||
|
Dispatch.put(find1, "Forward", "True");
|
||||||
|
// 设置格式
|
||||||
|
Dispatch.put(find1, "Format", "True");
|
||||||
|
// 大小写匹配
|
||||||
|
Dispatch.put(find1, "MatchCase", "True");
|
||||||
|
// 全字匹配
|
||||||
|
Dispatch.put(find1, "MatchWholeWord", "True");
|
||||||
|
// 查找并选中
|
||||||
|
return Dispatch.call(find1, "Execute").getBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向文档中添加 一个图片,
|
||||||
|
public static void insertJpeg(ActiveXComponent ax,String toFindText,String jpegFilePath,int width,int height) {
|
||||||
|
Dispatch selection = Dispatch.get(ax, "Selection").toDispatch();
|
||||||
|
// Dispatch image = Dispatch.get(selection, "InLineShapes").toDispatch();
|
||||||
|
// Dispatch.call(image, "AddPicture", jpegFilePath);
|
||||||
|
|
||||||
|
|
||||||
|
if (find(ax,toFindText)) {
|
||||||
|
Dispatch picture = Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(), "AddPicture", jpegFilePath).toDispatch(); // 添加图片
|
||||||
|
Dispatch.call(picture, "Select"); // 选中图片
|
||||||
|
Dispatch.put(picture, "Width", new Variant(width)); // 图片的宽度
|
||||||
|
Dispatch.put(picture, "Height", new Variant(height)); // 图片的高度
|
||||||
|
Dispatch ShapeRange = Dispatch.call(picture, "ConvertToShape").toDispatch(); // 取得图片区域
|
||||||
|
Dispatch WrapFormat = Dispatch.get(ShapeRange, "WrapFormat").toDispatch(); // 取得图片的格式对象
|
||||||
|
Dispatch.put(WrapFormat, "Type", 7); // 设置环绕格式(0 - 7)下面是参数说明
|
||||||
|
|
||||||
|
// wdWrapInline 7 将形状嵌入到文字中。
|
||||||
|
// wdWrapNone 3 将形状放在文字前面。请参阅 wdWrapFront 。
|
||||||
|
// wdWrapSquare 0 使文字环绕形状。行在形状的另一侧延续。
|
||||||
|
// wdWrapThrough 2 使文字环绕形状。
|
||||||
|
// wdWrapTight 1 使文字紧密地环绕形状。
|
||||||
|
// wdWrapTopBottom 4 将文字放在形状的上方和下方。
|
||||||
|
// wdWrapBehind 5 将形状放在文字后面。
|
||||||
|
// wdWrapFront 6 将形状放在文字前面。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 保存文档的更改
|
||||||
|
public static void save() {
|
||||||
|
Dispatch.call(document, "Save");
|
||||||
|
}
|
||||||
|
public static void closeDocument() {
|
||||||
|
// Close the document without saving changes
|
||||||
|
// 0 = wdDoNotSaveChanges
|
||||||
|
// -1 = wdSaveChanges
|
||||||
|
// -2 = wdPromptToSaveChanges
|
||||||
|
if(document != null) {
|
||||||
|
Dispatch.call(document, "Close", new Variant(false));
|
||||||
|
document = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void closeWord() {
|
||||||
|
Dispatch.call(MsWordApp, "Quit");
|
||||||
|
MsWordApp = null;
|
||||||
|
document = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openAnExistsFileTest(String wordFilePath,String toFindText,String imagePath,int width,int height) {
|
||||||
|
ActiveXComponent ax = null;
|
||||||
|
ax = new ActiveXComponent("Word.Application");
|
||||||
|
ax.setProperty("Visible", new Variant(false));// 是否前台打开word 程序,或者后台运行
|
||||||
|
Dispatch documents = Dispatch.get(ax, "Documents").toDispatch();
|
||||||
|
documents = Dispatch.call(documents, "Open", wordFilePath,
|
||||||
|
new Variant(true)/* 是否进行转换ConfirmConversions */,
|
||||||
|
new Variant(false)/* 是否只读 */).toDispatch();
|
||||||
|
//Dispatch selection = Dispatch.get(MsWordApp, "Selection").toDispatch();
|
||||||
|
insertJpeg(ax,toFindText,imagePath,width,height); // 插入图片(注意刚打开的word,光标处于开头,故,图片在最前方插入)
|
||||||
|
// word文件另存为pdf文件
|
||||||
|
String toAddress = splitSuffx(wordFilePath);
|
||||||
|
Dispatch.call(documents, "Save");
|
||||||
|
//Dispatch.call(documents, "Quit");
|
||||||
|
Dispatch.call(documents, "SaveAs", toAddress, wdFormatPDF);
|
||||||
|
Dispatch.call(documents, "Close", new Variant(false));
|
||||||
|
//save();
|
||||||
|
//closeDocument();
|
||||||
|
//closeWord();
|
||||||
|
// 关闭word文档
|
||||||
|
//Dispatch.call(documents, "Close", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean findText(Dispatch selection, String toFindText,String matchWholeWord) {
|
||||||
|
return findText(selection, toFindText, matchWholeWord, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找文本
|
||||||
|
* @param selection
|
||||||
|
* @param toFindText
|
||||||
|
* @param matchWholeWord 匹配全词
|
||||||
|
* @param matchWildcards 使用通配符
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean findText(Dispatch selection, String toFindText,String matchWholeWord, boolean matchWildcards) {
|
||||||
|
if (toFindText == null || "".equals(toFindText))
|
||||||
|
return false;
|
||||||
|
// 从selection所在位置开始查询
|
||||||
|
Dispatch find1 = Dispatch.call(selection, "Find").toDispatch();
|
||||||
|
// 设置要查找的内容
|
||||||
|
Dispatch.put(find1, "Text", toFindText);
|
||||||
|
// 向前查找
|
||||||
|
Dispatch.put(find1, "Forward", "True");
|
||||||
|
// 通配符
|
||||||
|
Dispatch.put(find1, "MatchWildcards", matchWildcards);
|
||||||
|
// 设置格式
|
||||||
|
Dispatch.put(find1, "Format", "True");
|
||||||
|
// 大小写匹配
|
||||||
|
Dispatch.put(find1, "MatchCase", "False");
|
||||||
|
// 全字匹配
|
||||||
|
Dispatch.put(find1, "MatchWholeWord", matchWholeWord);
|
||||||
|
// 查找并选中
|
||||||
|
return Dispatch.call(find1, "Execute").getBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入图片
|
||||||
|
*
|
||||||
|
* @Title: insertJpeg
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param source
|
||||||
|
* @param toFindText
|
||||||
|
* @param imgSource
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static byte[] insertJpeg(byte[] source, String toFindText, byte[] imgSource, int width, int height) {
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
Path tempFilePath = null;
|
||||||
|
Path imgTempFilePath = null;
|
||||||
|
byte[] result = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(tempFilePath, source);
|
||||||
|
docToPdfUtil.openDocument(tempFilePath.toString());
|
||||||
|
if (docToPdfUtil.findText(docToPdfUtil.selection, toFindText,"True")) {
|
||||||
|
imgTempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(imgTempFilePath, imgSource);
|
||||||
|
Dispatch picture = Dispatch.call(Dispatch.get(docToPdfUtil.selection, "InLineShapes").toDispatch(), "AddPicture", imgTempFilePath.toString()).toDispatch(); // 添加图片
|
||||||
|
Dispatch.call(picture, "Select"); // 选中图片
|
||||||
|
if (width!=0) {
|
||||||
|
Dispatch.put(picture, "Width", new Variant(width)); // 图片的宽度
|
||||||
|
Dispatch.put(picture, "Height", new Variant(height)); // 图片的高度
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch ShapeRange = Dispatch.call(picture, "ConvertToShape").toDispatch(); // 取得图片区域
|
||||||
|
// Dispatch WrapFormat = Dispatch.get(ShapeRange, "WrapFormat").toDispatch(); // 取得图片的格式对象
|
||||||
|
// Dispatch.put(WrapFormat, "Type", 0); // 设置环绕格式(0 - 7)下面是参数说明
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
if (tempFilePath != null) {
|
||||||
|
try {
|
||||||
|
result = Files.readAllBytes(tempFilePath);
|
||||||
|
Files.delete(tempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imgTempFilePath != null) {
|
||||||
|
try {
|
||||||
|
Files.delete(imgTempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("insert image=======consuming:{} milliseconds", System.currentTimeMillis() - t1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入图片
|
||||||
|
*
|
||||||
|
* @Title: insertJpeg
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param source
|
||||||
|
* @param toFindText
|
||||||
|
* @param imgSources
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static byte[] insertJpeg(byte[] source, String toFindText, List<byte[]> imgSources, int width, int height) {
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
Path tempFilePath = null;
|
||||||
|
Path imgTempFilePath = null;
|
||||||
|
byte[] result = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(tempFilePath, source);
|
||||||
|
docToPdfUtil.openDocument(tempFilePath.toString());
|
||||||
|
String replaceText = "";
|
||||||
|
for (int i = 0; i < imgSources.size(); i++) {
|
||||||
|
replaceText += "${" + toFindText + "_" + i + "}";
|
||||||
|
}
|
||||||
|
String searchText = "${" + toFindText + "}";
|
||||||
|
boolean flag = docToPdfUtil.findText(docToPdfUtil.selection, searchText, "True");
|
||||||
|
if (flag) {
|
||||||
|
setKeyAndValue(docToPdfUtil, replaceText, searchText);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < imgSources.size(); i++) {
|
||||||
|
Dispatch.call(docToPdfUtil.selection,"HomeKey",new Variant(6));
|
||||||
|
if (docToPdfUtil.findText(docToPdfUtil.selection, "${" + toFindText + "_" + i + "}" ,"True")) {
|
||||||
|
imgTempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(imgTempFilePath, imgSources.get(i));
|
||||||
|
Dispatch picture = Dispatch.call(Dispatch.get(docToPdfUtil.selection, "InLineShapes").toDispatch(), "AddPicture", imgTempFilePath.toString()).toDispatch(); // 添加图片
|
||||||
|
Dispatch.call(picture, "Select"); // 选中图片
|
||||||
|
if (width != 0) {
|
||||||
|
Dispatch.put(picture, "Width", new Variant(width)); // 图片的宽度
|
||||||
|
Dispatch.put(picture, "Height", new Variant(height)); // 图片的高度
|
||||||
|
}
|
||||||
|
// Dispatch ShapeRange = Dispatch.call(picture, "ConvertToShape").toDispatch(); // 取得图片区域
|
||||||
|
// Dispatch WrapFormat = Dispatch.get(ShapeRange, "WrapFormat").toDispatch(); // 取得图片的格式对象
|
||||||
|
// Dispatch.put(WrapFormat, "Type", 0); // 设置环绕格式(0 - 7)下面是参数说明
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
if (tempFilePath != null) {
|
||||||
|
try {
|
||||||
|
result = Files.readAllBytes(tempFilePath);
|
||||||
|
Files.delete(tempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imgTempFilePath != null) {
|
||||||
|
try {
|
||||||
|
Files.delete(imgTempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void insertJpeg(String wordFilePath, List<String> findTexts, List<String> imagePaths, List<Map<String, Object>> imageSelections) {
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
docToPdfUtil.openDocument(wordFilePath);
|
||||||
|
if (findTexts != null && findTexts.size() > 0) {
|
||||||
|
for (int i=0; i< findTexts.size(); i++) {
|
||||||
|
String toFindText = findTexts.get(i);
|
||||||
|
String imagePath = imagePaths.get(i);
|
||||||
|
Map<String, Object> imageSelection = imageSelections.get(i);
|
||||||
|
int height = CastUtil.castInt(imageSelection.get("Height"));
|
||||||
|
int width = CastUtil.castInt(imageSelection.get("Width"));
|
||||||
|
if (docToPdfUtil.findText(docToPdfUtil.selection, toFindText,"True")) {
|
||||||
|
Dispatch picture = Dispatch.call(Dispatch.get(docToPdfUtil.selection, "InLineShapes").toDispatch(), "AddPicture", imagePath).toDispatch(); // 添加图片
|
||||||
|
Dispatch.call(picture, "Select"); // 选中图片
|
||||||
|
if (width!=0) {
|
||||||
|
Dispatch.put(picture, "Width", new Variant(width)); // 图片的宽度
|
||||||
|
Dispatch.put(picture, "Height", new Variant(height)); // 图片的高度
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispatch ShapeRange = Dispatch.call(picture, "ConvertToShape").toDispatch(); // 取得图片区域
|
||||||
|
Dispatch WrapFormat = Dispatch.get(ShapeRange, "WrapFormat").toDispatch(); // 取得图片的格式对象
|
||||||
|
Dispatch.put(WrapFormat, "Type", 0); // 设置环绕格式(0 - 7)下面是参数说明
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换字段
|
||||||
|
*
|
||||||
|
* @Title: wordFindReplace
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param wordpath
|
||||||
|
* @param oldtext
|
||||||
|
* @param newtext
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String wordFindReplace(String wordpath,String oldtext,String newtext) {
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
docToPdfUtil.openDocument(wordpath);
|
||||||
|
boolean flag = docToPdfUtil.findText(docToPdfUtil.selection, oldtext,"True");
|
||||||
|
if (flag) {
|
||||||
|
Dispatch.put(docToPdfUtil.selection,"Text",newtext);
|
||||||
|
Dispatch.call(docToPdfUtil.selection, "MoveRight");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向word填充属性字段
|
||||||
|
*
|
||||||
|
* @Title: fieldToWord
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param source 源
|
||||||
|
* @param infoMap 属性字段
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static byte[] fieldToWord(byte[] source, Map<String, Object> infoMap) {
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
Path tempFilePath = null;
|
||||||
|
byte[] result = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(tempFilePath, source);
|
||||||
|
docToPdfUtil.openDocument(tempFilePath.toString());
|
||||||
|
for (String key : infoMap.keySet()) {
|
||||||
|
String replaceText = "${" + key.trim() + "}";
|
||||||
|
boolean flag = docToPdfUtil.findText(docToPdfUtil.selection, replaceText,"True");
|
||||||
|
if (flag) {
|
||||||
|
String value = CastUtil.castString(infoMap.get(key));
|
||||||
|
setKeyAndValue(docToPdfUtil, value, replaceText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
if (tempFilePath != null) {
|
||||||
|
try {
|
||||||
|
result = Files.readAllBytes(tempFilePath);
|
||||||
|
Files.delete(tempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("insert text=======consuming:{} milliseconds", System.currentTimeMillis() - t1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除占位符
|
||||||
|
* @param source
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte[] clearPlaceholder(byte[] source) {
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
Path tempFilePath = null;
|
||||||
|
byte[] result = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);
|
||||||
|
Files.write(tempFilePath, source);
|
||||||
|
docToPdfUtil.openDocument(tempFilePath.toString());
|
||||||
|
String replaceText = "$\\{*\\}";
|
||||||
|
boolean flag = docToPdfUtil.findText(docToPdfUtil.selection, replaceText, "True", true);
|
||||||
|
if (flag) {
|
||||||
|
setKeyAndValue(docToPdfUtil, "", replaceText, true);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
if (tempFilePath != null) {
|
||||||
|
try {
|
||||||
|
result = Files.readAllBytes(tempFilePath);
|
||||||
|
Files.delete(tempFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("clear placeholder=======consuming:{} milliseconds", System.currentTimeMillis() - t1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setKeyAndValue(DocToPdfUtil docToPdfUtil, String value, String replaceText) {
|
||||||
|
setKeyAndValue(docToPdfUtil, value, replaceText, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setKeyAndValue(DocToPdfUtil docToPdfUtil, String value,String replaceText, boolean matchWildcards) {
|
||||||
|
if (value == null) {
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
value = CastUtil.delHTMLTag(value);
|
||||||
|
if (value.indexOf("\n\n") != -1) {
|
||||||
|
value = value.replace("\n\n", CastUtil.castString((char) 11));
|
||||||
|
}
|
||||||
|
if (value.indexOf("\n") != -1) {
|
||||||
|
value = value.replace("\n", CastUtil.castString((char) 11));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispatch.put(docToPdfUtil.selection, "Text", value);
|
||||||
|
|
||||||
|
//Dispatch.call(docToPdfUtil.selection, "MoveStart");
|
||||||
|
Dispatch.call(docToPdfUtil.selection,"HomeKey",new Variant(6));
|
||||||
|
boolean flag = docToPdfUtil.findText(docToPdfUtil.selection, replaceText,"True", matchWildcards);
|
||||||
|
if (flag) {
|
||||||
|
setKeyAndValue(docToPdfUtil, value, replaceText, matchWildcards);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word转pdf
|
||||||
|
* @Title: wordCnoverPdf
|
||||||
|
* @author: xianjun
|
||||||
|
* @Description: TODO
|
||||||
|
* @param fromAddress
|
||||||
|
* @return
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
public static String wordCnoverPdf(String fromAddress) {
|
||||||
|
String toAddress = splitSuffx(fromAddress);
|
||||||
|
DocToPdfUtil docToPdfUtil = null;
|
||||||
|
try {
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
docToPdfUtil = new DocToPdfUtil();
|
||||||
|
docToPdfUtil.openDocument(fromAddress);
|
||||||
|
File tofile = new File(toAddress);
|
||||||
|
if (tofile.exists()) {
|
||||||
|
tofile.delete();
|
||||||
|
}
|
||||||
|
// word文件另存为pdf文件
|
||||||
|
Dispatch.call(docToPdfUtil.doc, "SaveAs", toAddress, wdFormatPDF);
|
||||||
|
// 关闭word文档
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("转换完成,总共耗时" + (endTime - startTime));
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
return toAddress;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if(docToPdfUtil != null) {
|
||||||
|
docToPdfUtil.cloaseDocument();
|
||||||
|
docToPdfUtil.close();
|
||||||
|
}
|
||||||
|
System.out.println("=============Error:文档转换失败:" + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
package com.optima.document.server.utils;/**
|
||||||
|
* Created by xianjun on 2019/3/22.16:30
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
import org.apache.poi.hwpf.model.PicturesTable;
|
||||||
|
import org.apache.poi.hwpf.usermodel.Bookmarks;
|
||||||
|
import org.apache.poi.hwpf.usermodel.Range;
|
||||||
|
import org.apache.poi.xwpf.usermodel.*;
|
||||||
|
import org.apache.xmlbeans.XmlToken;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
|
||||||
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
|
||||||
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
|
||||||
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文书替换工具类
|
||||||
|
* @author xianjun
|
||||||
|
* @version 2019/3/22 16:30
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PoiWordUtil {
|
||||||
|
/**
|
||||||
|
* word为doc后缀
|
||||||
|
*/
|
||||||
|
private static final String DOC = "doc";
|
||||||
|
/**
|
||||||
|
* word为docx后缀
|
||||||
|
*/
|
||||||
|
private static final String DOCX = "docx";
|
||||||
|
/**
|
||||||
|
* 服务器为windows
|
||||||
|
*/
|
||||||
|
private static final String SYSTEM_TYPE_W = "Windows";
|
||||||
|
/**
|
||||||
|
* 服务器为Linux
|
||||||
|
*/
|
||||||
|
private static final String SYSTEM_TYPE_L = "Linux";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误消息
|
||||||
|
*/
|
||||||
|
private static String errorMsg = "";
|
||||||
|
/**
|
||||||
|
* 模板路径
|
||||||
|
*/
|
||||||
|
private static String templatePath = "";
|
||||||
|
/**
|
||||||
|
* 新文件的路径
|
||||||
|
*/
|
||||||
|
private static String newFilePath = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文书临时存放的目录
|
||||||
|
*/
|
||||||
|
private static String tempFilePath = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换模板方法
|
||||||
|
* @param path 文书路径
|
||||||
|
* @param tempPath 临时路径
|
||||||
|
* @param paramMap 替换参数
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
// public static Map<String,String> executeWord(String path, String tempPath, Map<String, Object> paramMap) throws Exception {
|
||||||
|
// //获取模板路径
|
||||||
|
// getTemplate(path);
|
||||||
|
// //获取新文件生成路径
|
||||||
|
// getFileStore(path);
|
||||||
|
// newFilePath = tempPath;
|
||||||
|
// //判断模板类型
|
||||||
|
// if(templatePath.endsWith(DOC)){
|
||||||
|
// //处理03版word
|
||||||
|
// //replaceWordDoc(paramMap);
|
||||||
|
// }else if(templatePath.endsWith(DOCX)){
|
||||||
|
// //处理07版word
|
||||||
|
// replaceWordDocx(paramMap);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //返回处理结果(新生成文件路径、错误信息)
|
||||||
|
// Map<String,String> map = new HashMap<String,String>();
|
||||||
|
// map.put("newFilePath", newFilePath);
|
||||||
|
// map.put("errorMsg", errorMsg);
|
||||||
|
// return map;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换模板文本内容(2007)
|
||||||
|
* @param paramMap 替换参数
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private static void replaceWordDocx(Map<String, Object> paramMap) throws Exception{
|
||||||
|
InputStream is = new FileInputStream(tempFilePath);
|
||||||
|
XWPFDocument doc = new XWPFDocument(is);
|
||||||
|
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
|
||||||
|
Iterator<XWPFTable> it = doc.getTablesIterator();
|
||||||
|
XWPFParagraph para;
|
||||||
|
XWPFTable patab;
|
||||||
|
//替换文本
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
para = iterator.next();
|
||||||
|
replaceInParaDocx(doc, para, paramMap);
|
||||||
|
}
|
||||||
|
while (it.hasNext()) {
|
||||||
|
patab = it.next();
|
||||||
|
List<XWPFTableRow> rows = patab.getRows();
|
||||||
|
for (int i = 0; i < rows.size(); i++) {
|
||||||
|
XWPFTableRow row = rows.get(i);//读取每一列数据
|
||||||
|
List<XWPFTableCell> cells = row.getTableCells();
|
||||||
|
for (int j = 0; j < cells.size(); j++) {
|
||||||
|
XWPFTableCell cell = cells.get(j);
|
||||||
|
//输出当前的单元格的数据
|
||||||
|
//System.out.print(cell.getText() + "\t");
|
||||||
|
List<XWPFParagraph> paragraphs = cell.getParagraphs();
|
||||||
|
for (XWPFParagraph xwpfParagraph : paragraphs) {
|
||||||
|
replaceInParaDocx(doc, xwpfParagraph, paramMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//写出文件
|
||||||
|
OutputStream out = new FileOutputStream(newFilePath);
|
||||||
|
doc.write(out);
|
||||||
|
//关闭输出流
|
||||||
|
close(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换方法(2007)
|
||||||
|
* @param para
|
||||||
|
* @param paramMap
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void replaceInParaDocx(XWPFDocument doc, XWPFParagraph para, Map<String, Object> paramMap) throws Exception {
|
||||||
|
List<XWPFRun> runs;
|
||||||
|
Matcher matcher;
|
||||||
|
String imgPath = "";
|
||||||
|
int width = 100,height = 100;
|
||||||
|
String txt = para.getParagraphText();
|
||||||
|
if (matcher(txt.trim()).find()) {
|
||||||
|
runs = para.getRuns();
|
||||||
|
for (int i=0; i<runs.size(); i++) {
|
||||||
|
XWPFRun run = runs.get(i);
|
||||||
|
String runText = run.toString();
|
||||||
|
matcher = matcher(runText);
|
||||||
|
if (matcher.find()) {
|
||||||
|
Map<String,Object> infoMap = new HashMap<String,Object>();
|
||||||
|
if ((matcher = matcher(runText)).find()) {
|
||||||
|
System.err.println("查找替换标签:" + matcher.group());
|
||||||
|
String tx = matcher.group().substring(2,matcher.group().length()-1);
|
||||||
|
if (paramMap.get(tx) instanceof Map) {
|
||||||
|
infoMap = (Map<String,Object>)paramMap.get(tx);
|
||||||
|
if (runText.contains("_img") || runText.contains("_sign") || runText.contains("_map")) {
|
||||||
|
imgPath = CastUtil.castString(infoMap.get("Text"));
|
||||||
|
width = CastUtil.castInt(infoMap.get("Width"));
|
||||||
|
height = CastUtil.castInt(infoMap.get("Height"));
|
||||||
|
if (imgPath !=null && !"".equalsIgnoreCase(imgPath)) {
|
||||||
|
runText = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String tempText = CastUtil.castString(infoMap.get("Text"));
|
||||||
|
if (tempText != null && !"".equalsIgnoreCase(tempText)) {
|
||||||
|
runText = CastUtil.castString(infoMap.get("Text"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (runText.contains("_img") || runText.contains("_sign") || runText.contains("_map")) {
|
||||||
|
imgPath = CastUtil.castString(paramMap.get(tx));
|
||||||
|
if (imgPath !=null && !"".equalsIgnoreCase(imgPath)) {
|
||||||
|
runText = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String tempText = CastUtil.castString(paramMap.get(tx));
|
||||||
|
if (tempText != null && !"".equalsIgnoreCase(tempText)) {
|
||||||
|
runText = tempText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
|
||||||
|
//所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
|
||||||
|
para.removeRun(i);
|
||||||
|
XWPFRun newRun = para.insertNewRun(i);
|
||||||
|
newRun.setText(runText);
|
||||||
|
if(!infoMap.isEmpty()){
|
||||||
|
//设置字体样式
|
||||||
|
setFont(newRun, infoMap);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNoneEmpty(imgPath)){
|
||||||
|
//获得当前CTInline
|
||||||
|
CTInline inline = newRun.getCTR().addNewDrawing().addNewInline();
|
||||||
|
doc.addPictureData(new FileInputStream(imgPath), 5);
|
||||||
|
insertPicture(doc, inline, width, height);
|
||||||
|
}
|
||||||
|
imgPath = "";
|
||||||
|
//infoMap.clear();
|
||||||
|
System.err.println("替换");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2007字体样式设置
|
||||||
|
* @param run
|
||||||
|
* @param param
|
||||||
|
*/
|
||||||
|
private static void setFont(XWPFRun run, Map<String,Object> param) {
|
||||||
|
CTRPr pRpr = null;
|
||||||
|
if (run.getCTR() != null) {
|
||||||
|
pRpr = run.getCTR().getRPr();
|
||||||
|
if (pRpr == null) {
|
||||||
|
pRpr = run.getCTR().addNewRPr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置字体
|
||||||
|
if(param.get("Name") != null){
|
||||||
|
CTFonts fonts = pRpr.isSetRFonts()?pRpr.getRFonts():pRpr.addNewRFonts();
|
||||||
|
fonts.setAscii(param.get("Name").toString());
|
||||||
|
fonts.setEastAsia(param.get("Name").toString());
|
||||||
|
fonts.setHAnsi(param.get("Name").toString());
|
||||||
|
}
|
||||||
|
//粗体
|
||||||
|
run.setBold(param.get("Bold")!=null?true:false);
|
||||||
|
//斜体
|
||||||
|
run.setItalic(param.get("Italic")!=null?true:false);
|
||||||
|
//下划线
|
||||||
|
if (param.get("Underline") != null) {
|
||||||
|
run.setUnderline(UnderlinePatterns.SINGLE);
|
||||||
|
}
|
||||||
|
//字体大小
|
||||||
|
if(param.get("Size") != null){
|
||||||
|
CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
|
||||||
|
sz.setVal(new BigInteger(param.get("Size").toString()));
|
||||||
|
CTHpsMeasure szCs = pRpr.isSetSzCs() ? pRpr.getSzCs() : pRpr.addNewSzCs();
|
||||||
|
szCs.setVal(new BigInteger(param.get("Size").toString()));
|
||||||
|
}
|
||||||
|
//字体颜色
|
||||||
|
if (param.get("Color") != null) {
|
||||||
|
run.setColor(param.get("Color").toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入图片
|
||||||
|
*
|
||||||
|
* @param document
|
||||||
|
* @param inline
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void insertPicture(XWPFDocument document, CTInline inline, int width, int height) throws Exception {
|
||||||
|
int id = document.getAllPictures().size()-1;
|
||||||
|
final int EMU = 9525;
|
||||||
|
width *= EMU;
|
||||||
|
height *= EMU;
|
||||||
|
String blipId = document.getAllPictures().get(id).getPackageRelationship().getId();
|
||||||
|
|
||||||
|
String picXml = ""
|
||||||
|
+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
|
||||||
|
+ " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
|
||||||
|
+ " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
|
||||||
|
+ " <pic:nvPicPr>"
|
||||||
|
+ " <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>"
|
||||||
|
+ " <pic:cNvPicPr/>"
|
||||||
|
+ " </pic:nvPicPr>"
|
||||||
|
+ " <pic:blipFill>"
|
||||||
|
+ " <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
|
||||||
|
+ " <a:stretch>"
|
||||||
|
+ " <a:fillRect/>"
|
||||||
|
+ " </a:stretch>"
|
||||||
|
+ " </pic:blipFill>"
|
||||||
|
+ " <pic:spPr>"
|
||||||
|
+ " <a:xfrm>"
|
||||||
|
+ " <a:off x=\"0\" y=\"0\"/>"
|
||||||
|
+ " <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>"
|
||||||
|
+ " </a:xfrm>"
|
||||||
|
+ " <a:prstGeom prst=\"rect\">"
|
||||||
|
+ " <a:avLst/>"
|
||||||
|
+ " </a:prstGeom>"
|
||||||
|
+ " </pic:spPr>"
|
||||||
|
+ " </pic:pic>"
|
||||||
|
+ " </a:graphicData>"
|
||||||
|
+ "</a:graphic>";
|
||||||
|
|
||||||
|
inline.addNewGraphic().addNewGraphicData();
|
||||||
|
XmlToken xmlToken = null;
|
||||||
|
xmlToken = XmlToken.Factory.parse(picXml);
|
||||||
|
inline.set(xmlToken);
|
||||||
|
inline.setDistT(0);
|
||||||
|
inline.setDistB(0);
|
||||||
|
inline.setDistL(0);
|
||||||
|
inline.setDistR(0);
|
||||||
|
CTPositiveSize2D extent = inline.addNewExtent();
|
||||||
|
extent.setCx(width);
|
||||||
|
extent.setCy(height);
|
||||||
|
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
|
||||||
|
docPr.setId(id);
|
||||||
|
docPr.setName("IMG_" + id);
|
||||||
|
docPr.setDescr("IMG_" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换模板文本内容(2003)
|
||||||
|
* @param paramMap 替换参数
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private static void replaceWordDoc(Map<String, Object> paramMap) throws Exception{
|
||||||
|
InputStream is = new FileInputStream(templatePath);
|
||||||
|
HWPFDocument doc = new HWPFDocument(is);
|
||||||
|
Range bodyRange = doc.getRange();
|
||||||
|
//替换文本
|
||||||
|
replaceInParaDoc(doc, bodyRange, paramMap);
|
||||||
|
//输出新文件
|
||||||
|
FileOutputStream out = new FileOutputStream(newFilePath);
|
||||||
|
doc.write(out);
|
||||||
|
out.flush();
|
||||||
|
//关闭输出流
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换方法(2003)
|
||||||
|
* @param range
|
||||||
|
* @param paramMap
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void replaceInParaDoc(HWPFDocument doc, Range range, Map<String, Object> paramMap) {
|
||||||
|
Matcher matcher;
|
||||||
|
String imgPath = "";
|
||||||
|
int width = 0,height = 0;
|
||||||
|
while ((matcher = matcher(range.text())).find()) {
|
||||||
|
String key = matcher.group();
|
||||||
|
Map<String, Object> infoMap = (Map<String, Object>) paramMap.get(key);
|
||||||
|
if (infoMap.get("Type") !=null && "img".equalsIgnoreCase(CastUtil.castString(infoMap.get("Type")))) {
|
||||||
|
//处理图片
|
||||||
|
imgPath = infoMap.get("Path").toString();
|
||||||
|
width = Integer.parseInt(infoMap.get("Width").toString());
|
||||||
|
height = Integer.parseInt(infoMap.get("Height").toString());
|
||||||
|
} else {
|
||||||
|
range.replaceText(matcher.group(), String.valueOf(infoMap.get("Text")));
|
||||||
|
}
|
||||||
|
if(StringUtils.isNoneEmpty(imgPath)){
|
||||||
|
Bookmarks bookmarks = doc.getBookmarks();
|
||||||
|
PicturesTable picturesTable = doc.getPicturesTable();
|
||||||
|
}
|
||||||
|
imgPath = "";
|
||||||
|
/*int index = Integer.valueOf(matcher.group(1)) - 1;
|
||||||
|
if(index >= params.size()) break;
|
||||||
|
if(params.get(index) instanceof String){
|
||||||
|
range.replaceText(matcher.group(), String.valueOf(params.get(index)));
|
||||||
|
}else if(params.get(index) instanceof Map){
|
||||||
|
Map<String,Object> infoMap = (Map<String,Object>)params.get(index);
|
||||||
|
range.replaceText(matcher.group(), String.valueOf(infoMap.get("Text")));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正则匹配字符串
|
||||||
|
* @param str 带替换字符串
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Matcher matcher(String str) {
|
||||||
|
String remax = "\\$.+?}";
|
||||||
|
//String remax = "\\$\\{(.+?)\\}"Pattern.CASE_INSENSITIVE;
|
||||||
|
Pattern pattern = Pattern.compile(remax);
|
||||||
|
Matcher matcher = pattern.matcher(str);
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件模板路径
|
||||||
|
* @param path 模板文件路径
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private static void getTemplate(String path) throws Exception {
|
||||||
|
//String path = UploadFileUtils.getPath("write");
|
||||||
|
// String docPath = path + templateName + ".doc";
|
||||||
|
//String docxPath = path + templateName + ".docx";
|
||||||
|
templatePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 获取文件存储路径
|
||||||
|
// * @param templatePath 模板文件名称
|
||||||
|
// * @return
|
||||||
|
// * @throws IOException
|
||||||
|
// */
|
||||||
|
// private static void getFileStore(String templatePath) throws IOException {
|
||||||
|
// //操作系统类型(Windows、Linux)
|
||||||
|
// String sysType = UploadFileUtils.getPath("fileserver.system.type");
|
||||||
|
// //文件存储跟目录
|
||||||
|
// String fileRoot = UploadFileUtils.getPath("fileserver.local.root");
|
||||||
|
// //文件生产目录
|
||||||
|
// String fileStore = UploadFileUtils.getPath("fileserver.store");
|
||||||
|
// //生成文件名称
|
||||||
|
// String name = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
|
||||||
|
//
|
||||||
|
// if(SYSTEM_TYPE_W.equals(sysType)){
|
||||||
|
// //Windows
|
||||||
|
// tempFilePath = fileRoot + fileStore + "/" ;
|
||||||
|
// }else if(SYSTEM_TYPE_L.equals(sysType)){
|
||||||
|
// //Linux
|
||||||
|
// tempFilePath = File.separator + "usr/fileserver/";
|
||||||
|
// }else{
|
||||||
|
// //其他服务器系统处理
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //生成目录不存在创建目录
|
||||||
|
// File file = new File(tempFilePath);
|
||||||
|
// if(!file.exists()){
|
||||||
|
// file.mkdirs();
|
||||||
|
// }
|
||||||
|
// tempFilePath = tempFilePath + name + ".docx";
|
||||||
|
// FileUtils.copyFile(templatePath, tempFilePath);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭输出流
|
||||||
|
* @param os
|
||||||
|
*/
|
||||||
|
public static void close(OutputStream os) {
|
||||||
|
if (os != null) {
|
||||||
|
try {
|
||||||
|
os.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭输入流
|
||||||
|
* @param in
|
||||||
|
*/
|
||||||
|
public static void close(InputStream in) {
|
||||||
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word转pdf
|
||||||
|
* @throws Exception
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// public static byte[] wordToPdf(byte[] source) throws Exception{
|
||||||
|
// // 临时文件
|
||||||
|
// Path tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), null);;
|
||||||
|
// Files.write(tempFilePath, source);
|
||||||
|
// String command = "D:/OpenOffice4/program/soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\"";
|
||||||
|
// Process p = Runtime.getRuntime().exec(command);
|
||||||
|
// OpenOfficeConnection connection = new SocketOpenOfficeConnection();
|
||||||
|
// connection.connect();
|
||||||
|
// // 转换
|
||||||
|
// DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
|
||||||
|
// converter.convert(new ByteArrayInputStream(source), tempFilePath.toString());
|
||||||
|
// // 关闭连接
|
||||||
|
// connection.disconnect();
|
||||||
|
// // 关闭进程
|
||||||
|
// p.destroy();
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
5
server/src/main/resources/application.yml
Normal file
5
server/src/main/resources/application.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
server:
|
||||||
|
port: 8090
|
||||||
|
document:
|
||||||
|
doc-to-program: D:\\optima\\docto.exe
|
||||||
|
|
||||||
6
server/src/main/resources/banner.txt
Normal file
6
server/src/main/resources/banner.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
██████╗ ██████╗ ██████╗██╗ ██╗███╗ ███╗███████╗███╗ ██╗████████╗
|
||||||
|
██╔══██╗██╔═══██╗██╔════╝██║ ██║████╗ ████║██╔════╝████╗ ██║╚══██╔══╝
|
||||||
|
██║ ██║██║ ██║██║ ██║ ██║██╔████╔██║█████╗ ██╔██╗ ██║ ██║
|
||||||
|
██║ ██║██║ ██║██║ ██║ ██║██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║
|
||||||
|
██████╔╝╚██████╔╝╚██████╗╚██████╔╝██║ ╚═╝ ██║███████╗██║ ╚████║ ██║
|
||||||
|
╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝
|
||||||
102
tl-server/pom.xml
Normal file
102
tl-server/pom.xml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document-tl-server</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>document tl server</name>
|
||||||
|
<description>文档模版引擎服务</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.optima</groupId>
|
||||||
|
<artifactId>document-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.20</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.artofsolving</groupId>
|
||||||
|
<artifactId>jodconverter</artifactId>
|
||||||
|
<version>2.2.2</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${basedir}/src/main/resources/libs/jodconverter-2.2.2.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jodconverter</groupId>
|
||||||
|
<artifactId>jodconverter-core</artifactId>
|
||||||
|
<version>4.0.0-RELEASE</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
|
<artifactId>pdfbox-tools</artifactId>
|
||||||
|
<version>2.0.25</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.deepoove</groupId>
|
||||||
|
<artifactId>poi-tl</artifactId>
|
||||||
|
<version>1.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-to-slf4j</artifactId>
|
||||||
|
<version>2.17.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-api</artifactId>
|
||||||
|
<version>2.17.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includeSystemScope>true</includeSystemScope>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.optima.document.tl.server;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class DocumentServer {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DocumentServer.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package com.optima.document.tl.server.api;
|
||||||
|
|
||||||
|
import com.deepoove.poi.XWPFTemplate;
|
||||||
|
import com.deepoove.poi.config.Configure;
|
||||||
|
import com.deepoove.poi.data.PictureRenderData;
|
||||||
|
import com.deepoove.poi.data.TextRenderData;
|
||||||
|
import com.deepoove.poi.policy.ListRenderPolicy;
|
||||||
|
import com.deepoove.poi.policy.PictureRenderPolicy;
|
||||||
|
import com.deepoove.poi.render.RenderContext;
|
||||||
|
import com.deepoove.poi.template.run.RunTemplate;
|
||||||
|
import com.deepoove.poi.xwpf.BodyContainer;
|
||||||
|
import com.deepoove.poi.xwpf.BodyContainerFactory;
|
||||||
|
import com.optima.document.api.DocumentService;
|
||||||
|
import com.optima.document.tl.server.config.DocumentConfig;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.rendering.ImageType;
|
||||||
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务接口实现
|
||||||
|
* @author Elias
|
||||||
|
* @date 2021-09-28 16:18
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DocumentServiceImpl implements DocumentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* word模版引擎配置
|
||||||
|
*/
|
||||||
|
private static final Configure wtlConfig = Configure.builder().buildGramer("${", "}")
|
||||||
|
.setValidErrorHandler(new Configure.DiscardHandler())
|
||||||
|
.addPlugin('%', new ListRenderPolicy() {
|
||||||
|
@Override
|
||||||
|
public void doRender(RenderContext<List<Object>> context) throws Exception {
|
||||||
|
XWPFRun run = context.getRun();
|
||||||
|
List<?> dataList = context.getData();
|
||||||
|
Iterator<?> var5 = dataList.iterator();
|
||||||
|
while (var5.hasNext()) {
|
||||||
|
Object data = var5.next();
|
||||||
|
if (data instanceof TextRenderData) {
|
||||||
|
run.setText(((TextRenderData) data).getText());
|
||||||
|
if (var5.hasNext()) {
|
||||||
|
run.setText(",");
|
||||||
|
}
|
||||||
|
} else if (data instanceof PictureRenderData) {
|
||||||
|
PictureRenderPolicy.Helper.renderPicture(run, (PictureRenderData) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.setRenderDataComputeFactory(envModel ->
|
||||||
|
el -> {
|
||||||
|
Object data = envModel.getRoot();
|
||||||
|
if ("#this".equals(el)) {
|
||||||
|
return data;
|
||||||
|
} else if (data instanceof Map) {
|
||||||
|
Map dataMap = ((Map) data);
|
||||||
|
if (dataMap.containsKey(el)) {
|
||||||
|
return dataMap.get(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DocumentConfig documentConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] generateWord(byte[] templateData, Map<String, Object> dataModel) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
XWPFTemplate template = XWPFTemplate.compile(new ByteArrayInputStream(templateData), wtlConfig).render(dataModel);
|
||||||
|
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()){
|
||||||
|
template.write(bos);
|
||||||
|
log.info("word generate========consuming:{} milliseconds", System.currentTimeMillis() - start);
|
||||||
|
return bos.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("word generate error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] wordToPdf(byte[] source, boolean clear) {
|
||||||
|
try {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
if (clear) {
|
||||||
|
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||||||
|
XWPFTemplate template = XWPFTemplate.compile(new ByteArrayInputStream(source), wtlConfig);
|
||||||
|
BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(template.getXWPFDocument());
|
||||||
|
template.getElementTemplates().forEach(it -> {
|
||||||
|
if (it instanceof RunTemplate) {
|
||||||
|
RunTemplate rt = (RunTemplate) it;
|
||||||
|
bodyContainer.clearPlaceholder(rt.getRun());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
template.writeAndClose(bos);
|
||||||
|
source = bos.toByteArray();
|
||||||
|
log.info("清空占位符=======耗时:{} 毫秒", System.currentTimeMillis() - start);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("清空标签失败:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Path tempFilePath = Files.createTempFile(UUID.randomUUID().toString(), ".docx");
|
||||||
|
Files.write(tempFilePath, source);
|
||||||
|
|
||||||
|
Path pdfPath = Files.createTempFile(UUID.randomUUID().toString(), ".pdf");
|
||||||
|
|
||||||
|
try {
|
||||||
|
long begin = System.currentTimeMillis();
|
||||||
|
String command = "%s -f %s -O %s -T wdFormatPDF";
|
||||||
|
command = String.format(command, documentConfig.getDocToProgram(), tempFilePath, pdfPath);
|
||||||
|
Process p = Runtime.getRuntime().exec(command);
|
||||||
|
p.waitFor();
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("docto take time in millis:" + (end - begin));
|
||||||
|
return Files.readAllBytes(pdfPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
Files.delete(tempFilePath);
|
||||||
|
Files.delete(pdfPath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("word to pdf error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] wordToImage(byte[] source, String targetFormat) {
|
||||||
|
try {
|
||||||
|
byte[] pdfBytes = wordToPdf(source, true);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes));
|
||||||
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
|
BufferedImage bim = pdfRenderer.renderImageWithDPI(
|
||||||
|
0, 300, ImageType.RGB);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ImageIOUtil.writeImage(bim, targetFormat, bos, 300);
|
||||||
|
document.close();
|
||||||
|
log.info("word to image=======consuming:{} milliseconds", System.currentTimeMillis() - start);
|
||||||
|
|
||||||
|
return bos.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.optima.document.tl.server.config;
|
||||||
|
|
||||||
|
import com.optima.document.api.DocumentService;
|
||||||
|
import com.optima.document.tl.server.api.DocumentServiceImpl;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端配置
|
||||||
|
* @author Elias
|
||||||
|
* @date 2021-09-28 16:12
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "document")
|
||||||
|
@Data
|
||||||
|
public class DocumentConfig {
|
||||||
|
|
||||||
|
private String docToProgram;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档接口
|
||||||
|
* @return httpinvoker
|
||||||
|
*/
|
||||||
|
@Bean(name = "/document-service")
|
||||||
|
HttpInvokerServiceExporter wordService(DocumentService documentService) {
|
||||||
|
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
|
||||||
|
exporter.setService( documentService );
|
||||||
|
exporter.setServiceInterface(DocumentService.class);
|
||||||
|
return exporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
4
tl-server/src/main/resources/application.yml
Normal file
4
tl-server/src/main/resources/application.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
server:
|
||||||
|
port: 9004
|
||||||
|
document:
|
||||||
|
doc-to-program: C:\\DocumentServer\\docto.exe
|
||||||
6
tl-server/src/main/resources/banner.txt
Normal file
6
tl-server/src/main/resources/banner.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
██████╗ ██████╗ ██████╗██╗ ██╗███╗ ███╗███████╗███╗ ██╗████████╗
|
||||||
|
██╔══██╗██╔═══██╗██╔════╝██║ ██║████╗ ████║██╔════╝████╗ ██║╚══██╔══╝
|
||||||
|
██║ ██║██║ ██║██║ ██║ ██║██╔████╔██║█████╗ ██╔██╗ ██║ ██║
|
||||||
|
██║ ██║██║ ██║██║ ██║ ██║██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║
|
||||||
|
██████╔╝╚██████╔╝╚██████╗╚██████╔╝██║ ╚═╝ ██║███████╗██║ ╚████║ ██║
|
||||||
|
╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝
|
||||||
Reference in New Issue
Block a user