CentOS 7.9安装LibreOffice

安装JRE

[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf server-jre-8u301-linux-x64.tar.gz
[root@ecs src]# mv /usr/local/src/jdk1.8.0_301 /usr/local/jdk
[root@ecs src]# cat >> /etc/profile << EOF
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=\$JAVA_HOME/jre
export CLASSPATH=.:\$JAVA_HOME/lib:\$JRE_HOME/lib
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
[root@ecs src]# source /etc/profile

安装LibreOffice

  1. 安装主程序

    [root@ecs ~]# cd /usr/local/src
    [root@ecs src]# tar -zxvf LibreOffice_7.5.7.1_Linux_x86-64_rpm.tar.gz
    [root@ecs src]# cd LibreOffice_7.5.7.1_Linux_x86-64_rpm/RPMS && yum install -y *.rpm
  2. 安装中文语言包

    如需处理中文字体,必须安装中文语言包,否则无法正确识别中文字体名称。

    [root@ecs ~]# cd /usr/local/src
    [root@ecs ~]# tar -zxvf LibreOffice_7.5.7.1_Linux_x86-64_rpm_langpack_zh-CN.tar.gz
    [root@ecs ~]# cd LibreOffice_7.5.7.1_Linux_x86-64_rpm_langpack_zh-CN && yum install -y *.rpm
  3. 安装依赖

    [root@ecs ~]# yum install -y libXinerama cairo cups-libs

    不安装依赖会出现以下报错:

    • /opt/libreoffice7.5/program/oosplash: error while loading shared libraries: libXinerama.so.1: cannot open shared object file: No such file or directory
    • /opt/libreoffice7.5/program/soffice.bin: error while loading shared libraries: libcairo.so.2: cannot open shared object file: No such file or directory
    • /opt/libreoffice7.5/program/soffice.bin: error while loading shared libraries: libcups.so.2: cannot open shared object file: No such file or directory
  4. 安装中文字体

    必须安装中文字体,否则LibreOffice在处理文档时,中文字体会变成方框。

    [root@ecs ~]# cp /usr/local/src/fonts/*.ttf /usr/share/fonts
  5. 切换中文系统语言

    在非中文系统语言下,LibreOffice将无法识别中文字体名称,从而认为字体缺失,LibreOffice会使用第一个中文字体(按照拼音首字母排序)替换,如果找不到中文字体,则显示为方框。

    [root@ecs ~]# sed -i "/^LANG=\"en_US.UTF-8\"/cLANG=\"zh_CN.UTF-8\"" /etc/locale.conf
    [root@ecs ~]# reboot

    在安装CentOS 7.9时默认已经包含了大量语言包,因此可以直接修改/etc/locale.conf即可切换中文语言。但如果使用极简安装(如Docker CentOS),默认可能没有安装中文语言包,即使修改了/etc/locale.conf也无法显示中文,因为缺少语言包文件。

    查看系统已安装语言包:

    [root@ecs ~]# locale -a | grep zh_CN

    安装中文语言包

    [root@ecs ~]# localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8

    临时中文显示

    [root@ecs ~]# LC_ALL=zh_CN.UTF-8 date
    2026年 08月 06日 星期四 13:05:12 CS

    切换语言

    [root@ecs ~]# sed -i "/^LANG=/cLANG=\"zh_CN.UTF-8\"" /etc/locale.conf

    或者:

    [root@ecs ~]# localectl set-locale LANG=zh_CN.UTF-8

应用

  • 格式转换

    [root@ecs ~]# /opt/libreoffice7.5/program/soffice \
    --headless --invisible --convert-to pdf:writer_pdf_Export \
    --outdir /usr/local/src/ /usr/local/src/demo.docx 2>&1
  • 设置水印

    [root@ecs ~]# /opt/libreoffice7.5/program/soffice \
    --headless --invisible \
    --convert-to pdf:writer_pdf_Export:'{"Watermark":{"type":"string","value":"draft"}, "WatermarkColor":{"type":"long","value":"8355711"}, "WatermarkFontName":{"type":"string","value":"Times"}, "WatermarkFontHeight":{"type":"long","value":"100"}, "WatermarkRotateAngle":{"type":"long","value":"450"}}' \
    --outdir /usr/local/src/ /usr/local/src/demo.docx 2>&1
  • 服务器模式

    [root@ecs ~]# /opt/libreoffice7.5/program/soffice --headless \
    --accept="socket,host=127.0.0.1,port=3000;urp;" --nofirststartwizard &

    查看进程

    [root@ecs ~]# yum install -y net-tools
    [root@ecs ~]# netstat -anp | grep :3000
    tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      17416/soffice.bin
    [root@ecs ~]# ps -ef | grep libreoffice
    root     17394  1186  0 14:13 pts/0    00:00:00 /opt/libreoffice7.5/program/oosplash --headless --accept=socket,host=127.0.0.1,port=3000;urp; --nofirststartwizard
    root     17416 17394  0 14:13 pts/0    00:00:00 /opt/libreoffice7.5/program/soffice.bin --headless --accept=socket,host=127.0.0.1,port=3000;urp; --nofirststartwizard

unoconv

  • 安装

    [root@ecs ~]# cd /usr/local/src
    [root@ecs src]# tar -zxvf unoconv-0.8.2.tar.gz
    [root@ecs src]# cd unoconv-0.8.2 && make install
  • socket连接

    LibreOffice以服务器模式运行后,unoconv可以直接通过UNO协议进行通信。

    [root@ecs ~]# unoconv --connection 'socket,host=127.0.0.1,port=3000,tcpNoDelay=1;urp;StarOffice.ComponentContext' -f pdf demo.docx

    或者:

    [root@ecs ~]# unoconv -f pdf -p 3000 demo.docx
  • 监听模式

    unoconv包含直接模式(Direct Mode)监听模式(Listener Mode)

    可以以服务器模式启动LibreOffice,然后unoconv通过--connection-p直接连接。也可以使用unoconv --listener创建Listener(默认端口号2002)。

    [root@ecs ~]# unoconv --listener --server=0.0.0.0 --port=2002 &

    unoconv在执行文档转换时,默认尝试连接2002端口的Listener,如果unoconv --listener监听在其它端口,连接就会失败。连接失败后会自动启动一个2002端口的Listener。

    新的Listener会尝试启动soffice.bin,但由于unoconv --listener已经启动了soffice.bin进程,因此新的Listener将2002端口路由到soffice.bin后就终止Listener进程,转换动作没完成,终端会报错:Error: Unable to connect or start own listener. Aborting.

    解决方法(二选一):

    • 使用-p指定连接端口

      直接指定连接端口,避免新建listener。

      [root@ecs ~]# unoconv -f pdf -p 2002 demo.docx
    • 重新执行

      再次执行时,由于2002端口已经路由到soffice.bin,因此可以正常执行。

      [root@ecs ~]# unoconv -f pdf demo.docx

      查看执行过程:

      [root@ecs ~]# unoconv -vvv -f pdf demo.docx

    查看端口监听状态

    [root@ecs ~]# netstat -tlnp | grep 2002
    tcp        0      0 127.0.0.1:2002          0.0.0.0:*               LISTEN      1342/soffice.bin
    [root@ecs ~]# lsof -i:2002 -P -n
    soffice.b 1342 root   14u  IPv4 137618      0t0  TCP 127.0.0.1:2002 (LISTEN)
    [root@ecs ~]# ss -tlnp | grep -E "2002|3000"
    LISTEN     0      128    127.0.0.1:2002                     *:*                   users:(("soffice.bin",pid=1342,fd=14))
    LISTEN     0      128          *:3000                     *:*                   users:(("soffice.bin",pid=1342,fd=11))

    新的Listener在尝试启动soffice.bin时,如果没有发现已存在的soffice.bin进程,则会进入直接模式,执行完转换任务后,会自动终止Listener进程。直接模式每次都会创建soffice.bin进程,转换完成后再终止soffice.bin进程。

    因此在没有执行unoconv --listener的情况下,每次执行unoconv -f pdf demo.docx都需要等待一会儿,因为每次都需要先启动soffice.bin(比较消耗时间),转换完成后再终止soffice.bin。

Docker部署

自建镜像

  1. 创建Dockerfile

    FROM maisi/centos:7.9.2009
    
    WORKDIR /opt/libreoffice7.5/program
    
    ENV LANG=zh_CN.UTF-8 \
        LC_ALL=zh_CN.UTF-8
    
    ADD http://mirrors.aliyun.com/repo/Centos-7.repo /etc/yum.repos.d/CentOS-Base.repo
    RUN yum clean all && yum makecache
    
    RUN yum install libXinerama cairo cups-libs -y \
        yum clean all && \
        rm -rf /tmp/* rm -rf /var/cache/yum/* && \
        localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 && \
        sed -i "/^LANG=/cLANG=\"zh_CN.UTF-8\"" /etc/locale.conf && \
        ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    
    ADD LibreOffice_7.5.7.1_Linux_x86-64_rpm.tar.gz /usr/local/src/
    ADD LibreOffice_7.5.7.1_Linux_x86-64_rpm_langpack_zh-CN.tar.gz /usr/local/src/
    
    RUN cd /usr/local/src/LibreOffice_7.5.7.1_Linux_x86-64_rpm/RPMS/ && \
        yum localinstall *.rpm -y && \
        cd /usr/local/src/LibreOffice_7.5.7.1_Linux_x86-64_rpm_langpack_zh-CN/RPMS/ && \
        yum localinstall *.rpm -y
    
    ENV PATH=/opt/libreoffice7.5/program/:/opt/libreoffice7.5/program/python-core-3.8.18/bin:${PATH}
    
    ARG JDK_PATH=/usr/local/jdk
    ADD server-jre-8u351-linux-x64.tar.gz /usr/local/src/
    RUN mv /usr/local/src/jdk1.8.0_351 ${JDK_PATH}
    ENV JAVA_HOME=${JDK_PATH} \
        JRE_HOME=${JDK_PATH}/jre \
        CLASSPATH=.:${JDK_PATH}/lib:${JDK_PATH}/jre\lib \
        PATH=${JDK_PATH}/bin:${PATH}
    
    ADD setuptools-68.2.2.tar.gz /usr/local/src/
    ADD pip-23.3.1.tar.gz /usr/local/src/
    RUN cd /usr/local/src/setuptools-68.2.2 && \
        python setup.py install && \
        cd /usr/local/src/pip-23.3.1 && \
        python setup.py install && \
        rm -rf /usr/local/src/*.* && yum clean all
    
    RUN python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn unoserver flask gunicorn && \
        ln -s /opt/libreoffice7.5/program/soffice libreoffice && \
        sed -i s#/program/python.bin#/program/python#g /opt/libreoffice7.5/program/python-core-3.8.18/bin/unoserver && \
        sed -i s#/program/python.bin#/program/python#g /opt/libreoffice7.5/program/python-core-3.8.18/bin/unoconvert && \
        sed -i s#/program/python.bin#/program/python#g /opt/libreoffice7.5/program/python-core-3.8.18/bin/gunicorn
    
    COPY ./app /app
    
    EXPOSE 3000
    
    # CMD ["soffice", "--headless", "--accept=socket,host=0.0.0.0,port=3000;urp;", "--nofirststartwizard"]
    
    ENTRYPOINT unoserver --daemon & gunicorn -w 2 -b :3000 --chdir /app app:app
  2. 构建镜像

    [root@ecs ~]# docker build -t libreoffice:7.5.7.1-centos7.9.2009 --progress=plain --no-cache .
  3. 创建容器

    [root@ecs ~]# docker run --name=libreoffice \
    --restart unless-stopped \
    --privileged=true \
    -e TZ=Asia/Shanghai \
    -p 3000:3000 \
    -v /data/libreoffice:/data \
    -d libreoffice:7.5.7.1-centos7.9.2009
  4. 中文支持

    [root@ecs ~]# docker cp /data/libreoffice/fonts/STKaiti.ttf libreoffice:/opt/libreoffice7.5/share/fonts/truetype
    [root@ecs ~]# docker cp /data/libreoffice/fonts/方正仿宋_gbk.ttf libreoffice:/opt/libreoffice7.5/share/fonts/truetype
    [root@ecs ~]# docker restart libreoffice
  5. 上传镜像

    [root@ecs ~]# docker tag libreoffice:7.5.7.1-centos7.9.2009 registry.cn-shanghai.aliyuncs.com/maisi/libreoffice:7.5.7.1-centos7.9.2009
    [root@ecs ~]# docker push registry.cn-shanghai.aliyuncs.com/maisi/libreoffice:7.5.7.1-centos7.9.2009
  6. 格式转换

    • 容器内调用

      [root@ecs ~]# docker exec -it libreoffice /bin/bash
      [root@cc3b8a72e553 program]# ./soffice --headless --invisible --convert-to pdf --outdir /data /data/demo.docx
      [root@cc3b8a72e553 program]# unoconvert /data/demo.docx --convert-to pdf /data/demo.pdf
    • 宿主机调用

      [root@ecs ~]# docker exec libreoffice ./soffice --headless --invisible --convert-to pdf --outdir /data /data/demo.docx
    • 容器间调用

      [root@ecs ~]# docker run -it --rm --privileged --name node \
      -v /var/run/docker.sock:/var/run/docker.sock maisi/node:22-alpine sh
      / # apk add --no-cache docker-cli
      / # docker exec libreoffice ./soffice --version
    • api转换容器内文件

      [root@ecs ~]# curl -X POST http://127.0.0.1:3000/convert-to/pdf \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "file=/data/demo.docx"

      返回:/data/l29126e7v3nn037y6bi7vnbhkwramafq.pdf

      将容器内的文件/data/demo.docx转换后保存到容器/data/l29126e7v3nn037y6bi7vnbhkwramafq.pdf

    • api转换宿主机文件

      [root@ecs ~]# curl -X POST http://127.0.0.1:3000/convert-to/pdf \
      -F 'file=@/data/libreoffice/demo.docx' > /data/libreoffice/demo.pdf

      将宿主机的文件/data/libreoffice/demo.docx上传到api服务器,再将转换后的文件下载到宿主机/data/libreoffice/demo.pdf

使用LibreOffice/online

  1. 创建容器

    [root@ecs ~]# docker run --name=libreoffice \
    --restart unless-stopped \
    --privileged=true \
    -e TZ=Asia/Shanghai \
    -e username=admin -e password=123456 \
    -e extra_params=--o:ssl.enable=false \
    -p 9980:9980 \
    -v /data/libreoffice:/data:Z \
    -d libreoffice/online
    • 控制台不允许有特殊字符,如果密码设置为admin@123,实际密码会变成admin。
    • libreoffice/online默认开启ssl,强制https方式访问,如果需要通过http方式访问,必须关闭ssl。设置环境变量-e extra_params=--o:ssl.enable=false即可关闭ssl。
    • :Z:z仅在操作系统启用了SELinux时才有效。:z映射的卷可以被多个容器共享,而:Z仅限当前容器私有使用。

    浏览器访问:http://192.168.3.103:9980,返回OK表示部署已成功。

    管理中心:http://192.168.3.103:9980/loleaflet/dist/admin/admin.html

  2. 查看启动日志

    [root@ecs ~]# docker logs --tail 50 --follow --timestamps libreoffice
  3. 关闭ssl访问

    除了通过设置环境变量-e extra_params=--o:ssl.enable=false来关闭ssl之外,还可以通过修改配置文件来关闭ssl。

    [root@ecs ~]# docker exec -it libreoffice sed -i "/SSL support to enable./s/>true/>false/" /etc/loolwsd/loolwsd.xml
    [root@ecs ~]# docker restart libreoffice
  4. 允许使用本地文件系统

    [root@ecs ~]# docker exec -it libreoffice sed -i "/filesystem/s/false/true/" /etc/loolwsd/loolwsd.xml
    [root@ecs ~]# docker restart libreoffice

    打开本地文件:http://127.0.0.1:9980/loleaflet/dist/loleaflet.html?file_path=file:///data/hello.docx

    /data/hello.docx是容器内的文件路径,-v /data/libreoffice:/data:Z将宿主机的/data/libreoffice挂载到容器内的/data目录,因此/data/hello.docx实际是宿主机的/data/libreoffice/hello.docx

  5. 添加中文字体

    [root@ecs ~]# docker cp /data/libreoffice/fonts/STKaiti.ttf libreoffice:/opt/libreoffice/share/fonts/truetype
    [root@ecs ~]# docker cp /data/libreoffice/fonts/方正仿宋_gbk.ttf libreoffice:/opt/libreoffice/share/fonts/truetype
    [root@ecs ~]# docker restart libreoffice
  6. 转换文件

    [root@ecs ~]# curl -F "data=@/data/libreoffice/demo.docx" http://127.0.0.1:9980/lool/convert-to/pdf > demo.pdf

标签: none

添加新评论