初次提交
This commit is contained in:
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