Bläddra i källkod

文件预览完成

wanyuan 7 månader sedan
incheckning
e97f505631

+ 43 - 0
docker/CentOS-7-reg.repo

@@ -0,0 +1,43 @@
+# CentOS-Base.repo
+#
+# The mirror system uses the connecting IP address of the client and the
+# update status of each mirror to pick mirrors that are updated to and
+# geographically close to the client.  You should use this for CentOS updates
+# unless you are manually picking other mirrors.
+#
+# If the mirrorlist= does not work for you, as a fall back you can try the 
+# remarked out baseurl= line instead.
+#
+#
+ 
+[base]
+name=CentOS-$releasever - Base - repo.huaweicloud.com
+baseurl=https://repo.huaweicloud.com/centos/$releasever/os/$basearch/
+#mirrorlist=https://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
+gpgcheck=1
+gpgkey=https://repo.huaweicloud.com/centos/RPM-GPG-KEY-CentOS-7
+ 
+#released updates 
+[updates]
+name=CentOS-$releasever - Updates - repo.huaweicloud.com
+baseurl=https://repo.huaweicloud.com/centos/$releasever/updates/$basearch/
+#mirrorlist=https://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
+gpgcheck=1
+gpgkey=https://repo.huaweicloud.com/centos/RPM-GPG-KEY-CentOS-7
+ 
+#additional packages that may be useful
+[extras]
+name=CentOS-$releasever - Extras - repo.huaweicloud.com
+baseurl=https://repo.huaweicloud.com/centos/$releasever/extras/$basearch/
+#mirrorlist=https://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
+gpgcheck=1
+gpgkey=https://repo.huaweicloud.com/centos/RPM-GPG-KEY-CentOS-7
+ 
+#additional packages that extend functionality of existing packages
+[centosplus]
+name=CentOS-$releasever - Plus - repo.huaweicloud.com
+baseurl=https://repo.huaweicloud.com/centos/$releasever/centosplus/$basearch/
+#mirrorlist=https://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
+gpgcheck=1
+enabled=0
+gpgkey=https://repo.huaweicloud.com/centos/RPM-GPG-KEY-CentOS-7

+ 66 - 0
docker/Dockerfile

@@ -0,0 +1,66 @@
+# 基础镜像
+FROM centos:centos7
+
+USER root
+
+#容器内根:/mnt
+WORKDIR /mnt
+
+#安装openjdk17
+COPY ./jdk/openjdk-17+35_linux-x64_bin.tar.gz /mnt/openjdk.tar.gz
+RUN mkdir /usr/local/java && \
+    tar -zxvf /mnt/openjdk.tar.gz -C /usr/local/java/ && \
+    rm -rf /mnt/openjdk.tar.gz
+ENV JAVA_HOME=/usr/local/java/jdk-17
+ENV PATH=$JAVA_HOME/bin:$PATH
+
+# 安装 open office
+COPY ./openoffice/Apache_OpenOffice_4.1.15_Linux_x86-64_install-rpm_zh-CN.tar.gz /mnt/openoffice.tar.gz
+RUN tar -xzf /mnt/openoffice.tar.gz -C /mnt && \
+    cd /mnt/zh-CN/RPMS/ && \
+    rpm -ivh *.rpm && \
+    cd /mnt/zh-CN/RPMS/desktop-integration/ && \
+    rpm -ivh openoffice4.1.15-redhat-menus-4.1.15-9813.noarch.rpm && \
+    rm -rf /mnt/zh-CN
+
+
+# 将 CentOS7基础仓库修改为阿里云仓库,解决 yum报错
+RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
+COPY ./CentOS-7-reg.repo /etc/yum.repos.d/CentOS-Base.repo
+RUN yum clean all && \
+    yum makecache && \
+    yum install deltarpm -y
+
+# 安装缺失的包
+RUN yum install -y libXext.x86_64 freetype && \
+    yum groupinstall -y "X Window System"
+# 3.将我们准备的fonts字体,拷贝到/usr/share/fonts下面
+RUN mkdir -p /usr/share/fonts
+COPY ./openoffice/fonts /usr/share/fonts
+RUN cd /usr/share/fonts/ && \
+  chmod -R 755 /usr/share/fonts && \
+# 4.安装字体,和"X Window System"
+  yum install mkfontscale fontconfig -y && \
+  mkfontscale && \
+  mkfontdir && \
+  fc-cache -fv
+
+
+# 解决中文乱码问题
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV TZ Asia/Shanghai
+
+#指定环境(prod-生产,dev-开发)
+ENV APP_ACTIVE="prod"
+#卷目录(关联日志配置log4j2-prod.xml,关联存储配置application-prod.yml)
+VOLUME ["/mnt/logs","/mnt/storage","/mnt/jar"]
+#暴露容器端口为8012
+EXPOSE 8012
+
+#容器启动时执行的命令
+#ENTRYPOINT /opt/openoffice4/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;"-nofirststartwizard &
+ENTRYPOINT nohup java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Dspring.profiles.active=${APP_ACTIVE} -jar /mnt/jar/officeOnlineShow.jar
+
+

+ 1 - 0
docker/build_docker.sh

@@ -0,0 +1 @@
+docker build -t office_online_show:v1 .

BIN
docker/jar/officeOnlineShow.jar


BIN
docker/openoffice/Apache_OpenOffice_4.1.15_Linux_x86-64_install-rpm_zh-CN.tar.gz


+ 1 - 0
docker/run_docker.sh

@@ -0,0 +1 @@
+docker run --name office_online_show -d -p 8012:8012 -v /mnt/office_online_show/docker/logs:/mnt/logs -v /mnt/office_online_show/docker/jar:/mnt/jar -v /mnt/office_online_show/docker/storage:/mnt/storage office_online_show:v1

+ 108 - 0
pom.xml

@@ -0,0 +1,108 @@
+<?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>3.1.0</version>
+    </parent>
+    <groupId>com.kingtom.office</groupId>
+    <artifactId>office-online-show</artifactId>
+    <version>1.0</version>
+    <properties>
+        <java.version>17</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jodconverter.version>4.4.7</jodconverter.version>
+        <hutool.version>5.8.29</hutool.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-quartz</artifactId>
+        </dependency>
+        <!-- jodconverter-->
+        <dependency>
+            <groupId>org.jodconverter</groupId>
+            <artifactId>jodconverter-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jodconverter</groupId>
+            <artifactId>jodconverter-local</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jodconverter</groupId>
+            <artifactId>jodconverter-spring-boot-starter</artifactId>
+        </dependency>
+        <!--lombok-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>officeOnlineShow</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.jodconverter</groupId>
+                <artifactId>jodconverter-core</artifactId>
+                <version>${jodconverter.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jodconverter</groupId>
+                <artifactId>jodconverter-local</artifactId>
+                <version>${jodconverter.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jodconverter</groupId>
+                <artifactId>jodconverter-spring-boot-starter</artifactId>
+                <version>${jodconverter.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <url>http://116.204.115.13:8081/repository/maven-releases/</url>
+        </repository>
+        <snapshotRepository>
+            <id>snapshots</id>
+            <url>http://116.204.115.13:8081/repository/maven-snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+</project>

+ 23 - 0
src/main/java/com/kingtom/office/OfficeOnlineShowApplication.java

@@ -0,0 +1,23 @@
+package com.kingtom.office;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * 应用模块名称<p>
+ * 代码描述<p>
+ * Copyright: Copyright (C) 2024 KingTom
+ * , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司<p>
+ *
+ * @author wany
+ * @since 2024/8/5
+ */
+@EnableScheduling
+@SpringBootApplication
+public class OfficeOnlineShowApplication{
+    public static void main(String[] args){
+        SpringApplication.run(OfficeOnlineShowApplication.class, args);
+    }
+}

+ 22 - 0
src/main/java/com/kingtom/office/config/AppConfig.java

@@ -0,0 +1,22 @@
+package com.kingtom.office.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 应用模块名称<p>
+ * 代码描述<p>
+ * Copyright: Copyright (C) 2024 KingTom
+ * , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司<p>
+ *
+ * @author wany
+ * @since 2024/8/5
+ */
+@Configuration
+@ConfigurationProperties(prefix = "app")
+@Data
+public class AppConfig{
+    private String fileHome;
+}

+ 84 - 0
src/main/java/com/kingtom/office/controller/OfficeController.java

@@ -0,0 +1,84 @@
+package com.kingtom.office.controller;
+
+import java.io.*;
+import java.util.UUID;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import com.kingtom.office.config.AppConfig;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jodconverter.core.DocumentConverter;
+import org.jodconverter.core.office.OfficeException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 应用模块名称<p>
+ * 代码描述<p>
+ * Copyright: Copyright (C) 2024 KingTom
+ * , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司<p>
+ *
+ * @author wany
+ * @since 2024/8/5
+ */
+@Controller
+@RequestMapping("office")
+public class OfficeController{
+
+    @Autowired
+    private DocumentConverter converter;
+
+    @Autowired
+    private AppConfig appConfig;
+
+    private static final String FORMAT =
+            File.separator + "yyyy" + File.separator + "MM" + File.separator + "dd" + File.separator;
+
+    @PostMapping("toPdf")
+    public void toPdf(@RequestParam("file") MultipartFile file, @RequestParam("fileType") String fileType,
+            HttpServletResponse response) throws IOException, OfficeException{
+        String uuid = StringUtils.replace(UUID.randomUUID().toString(), "-", "");
+
+        File srcFile = new File(getFilePath() + uuid + fileType);
+        FileUtil.copyFile(file.getInputStream(), srcFile);
+
+        String fileName = uuid + ".pdf";
+        File targetFile = new File(getFilePath() + fileName);
+        converter.convert(srcFile).to(targetFile).execute();
+        output(response, fileName, targetFile);
+    }
+
+    private static void output(HttpServletResponse response, String fileName, File file) throws IOException{
+        try{
+            response.setContentType("application/pdf");
+            response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
+            FileInputStream fis = new FileInputStream(file);
+            OutputStream out = response.getOutputStream();
+            byte[] buffer = new byte[4096];
+            int bytesRead;
+            while((bytesRead = fis.read(buffer)) != -1){
+                out.write(buffer, 0, bytesRead);
+            }
+            fis.close();
+            out.flush();
+            out.close();
+        } catch(Exception e){
+            response.setContentType("application/json;charset=UTF-8");
+            PrintWriter writer = response.getWriter();
+            String json = "{\"error\":\"" + e.getMessage() + "\"}";
+            writer.print(json);
+            writer.flush();
+            writer.close();
+        }
+    }
+
+    private String getFilePath(){
+        return appConfig.getFileHome() + DateUtil.format(DateUtil.date(), FORMAT);
+    }
+}

+ 40 - 0
src/main/java/com/kingtom/office/job/Job.java

@@ -0,0 +1,40 @@
+package com.kingtom.office.job;
+
+import java.io.File;
+import java.util.Date;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import com.kingtom.office.config.AppConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 应用模块名称<p>
+ * 代码描述<p>
+ * Copyright: Copyright (C) 2024 KingTom
+ * , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司<p>
+ *
+ * @author wany
+ * @since 2024/8/5
+ */
+@Component
+@Slf4j
+public class Job{
+
+    @Autowired
+    private AppConfig appConfig;
+
+    @Scheduled(cron = "0 0 23 * * 0") // 每周日晚上11点执行
+    public void cleanUpDirectory(){
+        File directory = new File(appConfig.getFileHome());
+        if(!directory.exists()){
+            return;
+        }
+        FileUtil.del(directory);
+        log.info("Directory cleaned at: {}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+    }
+}

+ 23 - 0
src/main/resources/application-local.yml

@@ -0,0 +1,23 @@
+server:
+  port: 8012
+  servlet:
+    context-path: /apis
+spring:
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 200MB
+app:
+  file-home: D:/pdf
+jodconverter:
+  local:
+    enabled: true
+    office-home: C:/Program Files (x86)/OpenOffice 4
+    port-numbers:
+      - 10000
+      - 10001
+#logging:
+logging:
+  level:
+    root: info
+#  config: classpath:log4j2-local.xml

+ 42 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,42 @@
+server:
+  port: 8012
+  servlet:
+    context-path: /apis
+spring:
+  servlet:
+    multipart:
+      max-file-size: 200MB
+      max-request-size: 300MB
+app:
+  file-home: /mnt/storage
+jodconverter:
+  local:
+    enabled: true
+    office-home: /opt/openoffice4
+#    office-home: /opt/openoffice4/program
+    port-numbers:
+      - 10000
+      - 10001
+      - 10002
+      - 10003
+      - 10004
+      - 10005
+      - 10006
+      - 10007
+      - 10008
+      - 10009
+      - 10010
+      - 10011
+      - 10012
+      - 10013
+      - 10014
+      - 10015
+      - 10016
+      - 10017
+      - 10018
+      - 10019
+logging:
+  level:
+    root: info
+#logging:
+#  config: classpath:log4j2-local.xml

+ 6 - 0
src/main/resources/application.yml

@@ -0,0 +1,6 @@
+spring:
+  profiles:
+    active: local
+    group:
+      local: local
+      prod: prod

+ 43 - 0
src/main/resources/log4j2-local.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <properties>
+        <property name="logBase">~/</property>
+    </properties>
+
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout charset="UTF-8" pattern="[%d] [%X{TRACE_ID}] [%-5p] [%t] [%c] - %m%n"/>
+        </Console>
+        <RollingFile name="AccessFile" fileName="${logBase}/access.log" filePattern="${logBase}/access.%d{yyyy-MM-dd}.log">
+            <PatternLayout pattern="[%d] [%X{TRACE_ID}] [%-5p] [%t] [%c] - %m%n"/>
+            <Policies>
+                <!-- 设置日志文件切分参数 -->
+                <OnStartupTriggeringPolicy/>
+                <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
+                <SizeBasedTriggeringPolicy size="500 MB"/>
+                <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
+                <TimeBasedTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy max="100"/>
+        </RollingFile>
+        <RollingFile name="ErrorFile" fileName="${logBase}/error.log" filePattern="${logBase}/error.%d{yyyy-MM-dd}.log">
+            <Filters>
+                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
+            </Filters>
+            <PatternLayout pattern="[%d] [%X{TRACE_ID}] [error] [%t] [%c] - %m%n"/>
+            <TimeBasedTriggeringPolicy/>
+        </RollingFile>
+    </Appenders>
+
+    <Loggers>
+        <Root level="info">
+            <AppenderRef ref="Console" level="all"/>
+            <AppenderRef ref="AccessFile" level="info"/>
+            <AppenderRef ref="ErrorFile" level="warn"/>
+        </Root>
+        <Logger name="org.springframework.boot.web.embedded" level="warn"/>
+        <Logger name="org.springframework" level="warn"/>
+        <Logger name="org.jodconverter" level="info"/>
+        <logger name="com.kingtom" level="info"/>
+    </Loggers>
+</configuration>

+ 43 - 0
src/main/resources/log4j2-prod.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <properties>
+        <property name="logBase">/mnt/logs/</property>
+    </properties>
+
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout charset="UTF-8" pattern="[%d] [%X{TRACE_ID}] [%-5p] [%t] [%c] - %m%n"/>
+        </Console>
+        <RollingFile name="AccessFile" fileName="${logBase}/access.log" filePattern="${logBase}/access.%d{yyyy-MM-dd}.log">
+            <PatternLayout pattern="[%d] [%X{TRACE_ID}] [%-5p] [%t] [%c] - %m%n"/>
+            <Policies>
+                <!-- 设置日志文件切分参数 -->
+                <OnStartupTriggeringPolicy/>
+                <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
+                <SizeBasedTriggeringPolicy size="500 MB"/>
+                <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
+                <TimeBasedTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy max="100"/>
+        </RollingFile>
+        <RollingFile name="ErrorFile" fileName="${logBase}/error.log" filePattern="${logBase}/error.%d{yyyy-MM-dd}.log">
+            <Filters>
+                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
+            </Filters>
+            <PatternLayout pattern="[%d] [%X{TRACE_ID}] [error] [%t] [%c] - %m%n"/>
+            <TimeBasedTriggeringPolicy/>
+        </RollingFile>
+    </Appenders>
+
+    <Loggers>
+        <Root level="info">
+            <AppenderRef ref="Console" level="all"/>
+            <AppenderRef ref="AccessFile" level="info"/>
+            <AppenderRef ref="ErrorFile" level="warn"/>
+        </Root>
+        <Logger name="org.springframework.boot.web.embedded" level="warn"/>
+        <Logger name="org.springframework" level="warn"/>
+        <Logger name="org.jodconverter" level="info"/>
+        <logger name="com.kingtom" level="info"/>
+    </Loggers>
+</configuration>