容器中使用wps转pdf

  1. 1. 需求
  2. 2. 基础镜像
  3. 3. 安装wps
  4. 4. 安装字体
  5. 5. 安装python环境
  6. 6. 转换脚本doc->pdf
  7. 7. excel->pdf
  8. 8. ppt->pdf
  9. 9. 转换pdf
  10. 10. 问题
  11. 11. openjdk8
  12. 12. docker打包
  13. 13. Dockerfile
  14. 14. new.desktop
  15. 15. docker-compose
  16. 16. 参考资料
  • RUN ON SERVER
    1. 1. 镜像地址
    2. 2. 制作镜像
    3. 3. 更换国内源
    4. 4. 制作镜像
      1. 4.1. 文档互转
    5. 5. Run On Server
    6. 6. EULA
    7. 7. 转换pdf
    8. 8. 问题
    9. 9. 使用示例

  • 202205062006618

    需求

    容器中使用wps转换pdf的功能

    基础镜像

    1
    2
    3
    4
    5
    # 启动镜像并设置登陆密码
    # 该镜像存在一些问题,导致自定义的服务无法开机自启动
    #docker run -it --rm -p 6080:80 -p 5900:5900 -e VNC_PASSWORD=mypassword dorowu/ubuntu-desktop-lxde-vnc
    # 新基础镜像
    docker run -d -p 5901:5901 -e VNCPASS='vncpass' fullaxx/ubuntu-desktop

    202205061922065

    202205061923231

    安装wps

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #下载wps
    wget -c https://wps-linux-personal.wpscdn.cn/wps/download/ep/Linux2019/10976/wps-office_11.1.0.10976_amd64.deb?t=1742895472&k=abf8e47591107d53b7f91f2d46905dca

    #https://wps-linux-personal.wpscdn.cn/wps/download/ep/Linux2023/17900/wps-office_12.1.0.17900_amd64.deb?t=1742895472&k=abf8e47591107d53b7f91f2d46905dca
    # 依赖
    apt update
    apt install libglu1-mesa bsdmainutils qt5-default xdg-utils
    # 安装
    dpkg -i wps-office_11.1.0.10976_amd64.deb

    安装字体

    建议复制Windows下的所有字体,否则转换之后会因为字体缺失导致转换后的pdf和win下预览的不一致.

    wps-font-symbols

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #拷贝字体到 usr/share/fonts
    cp -r ./wps-font-symbols /usr/share/fonts/

    #生成字体缓存信息
    cd /usr/share/fonts/wps-font-symbols

    mkfontdir

    mkfontscale

    fc-cache

    安装python环境

    • 缺少python3-lxml会报错:libxslt.so.1: cannot open shared object file
    1
    2
    3
    4
    apt update
    apt install python3 python3-pip python3-lxml
    # 安装pywpsrpc
    pip install pywpsrpc -i https://pypi.tuna.tsinghua.edu.cn/simple

    转换脚本doc->pdf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    #!/usr/bin/python3

    #**
    # * Copyright (c) 2020 Weitian Leung
    # *
    # * This file is part of pywpsrpc.
    # *
    # * This file is distributed under the MIT License.
    # * See the LICENSE file for details.
    # *
    #*

    import os
    import sys
    import argparse

    from pywpsrpc.rpcwpsapi import (createWpsRpcInstance, wpsapi)
    from pywpsrpc.common import (S_OK, QtApp)


    formats = {
    "doc": wpsapi.wdFormatDocument,
    "docx": wpsapi.wdFormatXMLDocument,
    "rtf": wpsapi.wdFormatRTF,
    "html": wpsapi.wdFormatHTML,
    "pdf": wpsapi.wdFormatPDF,
    "xml": wpsapi.wdFormatXML,
    }


    class ConvertException(Exception):

    def __init__(self, text, hr):
    self.text = text
    self.hr = hr

    def __str__(self):
    return """Convert failed:
    Details: {}
    ErrCode: {}
    """.format(self.text, hex(self.hr & 0xFFFFFFFF))


    def convert_to(paths, format, abort_on_fails=False):
    hr, rpc = createWpsRpcInstance()
    if hr != S_OK:
    raise ConvertException("Can't create the rpc instance", hr)

    hr, app = rpc.getWpsApplication()
    if hr != S_OK:
    raise ConvertException("Can't get the application", hr)

    # we don't need the gui
    app.Visible = False

    docs = app.Documents

    def _handle_result(hr):
    if abort_on_fails and hr != S_OK:
    raise ConvertException("convert_file failed", hr)

    for path in paths:
    abs_path = os.path.realpath(path)
    if os.path.isdir(abs_path):
    files = [(os.path.join(abs_path, f)) for f in os.listdir(abs_path)]
    for file in files:
    hr = convert_file(file, docs, format)
    _handle_result(hr)
    else:
    hr = convert_file(abs_path, docs, format)
    _handle_result(hr)

    app.Quit()


    def convert_file(file, docs, format):
    hr, doc = docs.Open(file, ReadOnly=True)
    if hr != S_OK:
    return hr

    out_dir = os.path.dirname(os.path.realpath(file)) + "/out"
    os.makedirs(out_dir, exist_ok=True)

    # you have to handle if the new_file already exists
    new_file = out_dir + "/" + os.path.splitext(os.path.basename(file))[0] + "." + format
    ret = doc.SaveAs2(new_file, FileFormat=formats[format])

    # always close the doc
    doc.Close(wpsapi.wdDoNotSaveChanges)

    return ret


    def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--format", "-f",
    required=True,
    metavar="<DOC_TYPE>",
    choices=["doc", "docx", "rtf", "html", "pdf", "xml"],
    help="convert to <DOC_TYPE>,")

    parser.add_argument("--abort", "-a",
    action="store_true",
    help="abort if one convert fails")

    parser.add_argument("path",
    metavar="<path>",
    nargs='+',
    help="the <path> can be one or more file or folder")

    args = parser.parse_args()

    qApp = QtApp(sys.argv)

    try:
    convert_to(args.path, args.format, args.abort)
    except ConvertException as e:
    print(e)


    if __name__ == "__main__":
    main()

    excel->pdf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    #!/usr/bin/python3
    # -- coding: utf-8 -
    # **
    # * Copyright (c) 2020 cong.zheng
    # *
    # * This file is part of pywpsrpc.
    # *
    # * This file is distributed under the MIT License.
    # * See the LICENSE file for details.
    # *
    # *

    import os
    import subprocess
    import sys

    import argparse

    from pywpsrpc.rpcetapi import (createEtRpcInstance, etapi)

    from pywpsrpc.common import (S_OK, QtApp)

    formats = {
    "pdf": etapi.XlFixedFormatType.xlTypePDF,
    }


    class ConvertException(Exception):

    def __init__(self, text, hr):
    self.text = text
    self.hr = hr

    def __str__(self):
    return """Convert failed:
    Details: {}
    ErrCode: {}
    """.format(self.text, hex(self.hr & 0xFFFFFFFF))


    def convert_to(paths, format, abort_on_fails=False):
    hr, rpc = createEtRpcInstance()
    if hr != S_OK:
    raise ConvertException("Can't create the rpc instance", hr)

    hr, app = rpc.getEtApplication()
    if hr != S_OK:
    raise ConvertException("Can't get the application", hr)

    # we don't need the gui
    app.Visible = False

    #docs = app.Workbooks

    def _handle_result(hr):
    if abort_on_fails and hr != S_OK:
    raise ConvertException("convert_file failed", hr)

    for path in paths:
    abs_path = os.path.realpath(path)
    if os.path.isdir(abs_path):
    files = [(os.path.join(abs_path, f)) for f in os.listdir(abs_path)]
    for file in files:
    hr = convert_file(file, app, format)
    _handle_result(hr)
    else:
    hr = convert_file(abs_path, app, format)
    _handle_result(hr)

    app.Quit()


    def convert_file(file, app, format):
    hr, doc = app.Workbooks.Open(file, Password='xxx', ReadOnly=True)
    if hr != S_OK:
    return hr
    # 设置横向打印,不需要可以注释掉
    app.Worksheets(0).PageSetup.Orientation = etapi.xlLandscape

    out_dir = os.path.dirname(os.path.realpath(file)) + "/out"
    os.makedirs(out_dir, exist_ok=True)

    # you have to handle if the new_file already exists
    new_file = out_dir + "/" + os.path.splitext(os.path.basename(file))[0] + "." + format
    ret = doc.ExportAsFixedFormat(formats[format], new_file)

    # always close the doc
    doc.Close()

    return ret


    def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--format", "-f",
    required=True,
    metavar="<DOC_TYPE>",
    choices=["pdf"],
    help="convert to <DOC_TYPE>,")

    parser.add_argument("--abort", "-a",
    action="store_true",
    help="abort if one convert fails")

    parser.add_argument("path",
    metavar="<path>",
    nargs='+',
    help="the <path> can be one or more file or folder")

    args = parser.parse_args()

    qApp = QtApp(sys.argv)
    try:
    convert_to(args.path, args.format, args.abort)
    print("covert over")
    except Exception as e:
    print(e)
    finally:
    # ubuntu
    # apt install psmisc
    print("kill all et")
    subprocess.call("killall -9 et", shell=True)


    if __name__ == "__main__":
    main()

    ppt->pdf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #!/usr/bin/python3
    # -- coding: utf-8 -
    # **
    # * Copyright (c) 2020 cong.zheng
    # *
    # * This file is part of pywpsrpc.
    # *
    # * This file is distributed under the MIT License.
    # * See the LICENSE file for details.
    # *
    # *

    import os
    import subprocess
    import sys

    import argparse

    from pywpsrpc.rpcwppapi import (createWppRpcInstance, wppapi)
    from pywpsrpc.common import (S_OK, QtApp)

    formats = {
    "pdf": wppapi.PpSaveAsFileType.ppSaveAsPDF,
    }


    class ConvertException(Exception):

    def __init__(self, text, hr):
    self.text = text
    self.hr = hr

    def __str__(self):
    return """Convert failed:
    Details: {}
    ErrCode: {}
    """.format(self.text, hex(self.hr & 0xFFFFFFFF))


    def convert_to(paths, format, abort_on_fails=False):
    hr, rpc = createWppRpcInstance()
    if hr != S_OK:
    raise ConvertException("Can't create the rpc instance", hr)

    hr, app = rpc.getWppApplication()
    if hr != S_OK:
    raise ConvertException("Can't get the application", hr)

    # we don't need the gui
    # Call 'put_Visible()' failed with 0x80010105
    # app.Visible = wppapi.MsoTriState.msoFalse

    docs = app.Presentations

    def _handle_result(hr):
    if abort_on_fails and hr != S_OK:
    raise ConvertException("convert_file failed", hr)

    for path in paths:
    abs_path = os.path.realpath(path)
    if os.path.isdir(abs_path):
    files = [(os.path.join(abs_path, f)) for f in os.listdir(abs_path)]
    for file in files:
    hr = convert_file(file, docs, format)
    _handle_result(hr)
    else:
    hr = convert_file(abs_path, docs, format)
    _handle_result(hr)

    app.Quit()


    def convert_file(file, docs, format):
    hr, doc = docs.Open(file, ReadOnly=True)
    if hr != S_OK:
    return hr

    out_dir = os.path.dirname(os.path.realpath(file)) + "/out"
    os.makedirs(out_dir, exist_ok=True)

    # you have to handle if the new_file already exists
    new_file = out_dir + "/" + os.path.splitext(os.path.basename(file))[0] + "." + format
    ret = doc.SaveAs(new_file, formats[format])

    # always close the doc
    doc.Close()

    return ret


    def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--format", "-f",
    required=True,
    metavar="<DOC_TYPE>",
    choices=["pdf"],
    help="convert to <DOC_TYPE>,")

    parser.add_argument("--abort", "-a",
    action="store_true",
    help="abort if one convert fails")

    parser.add_argument("path",
    metavar="<path>",
    nargs='+',
    help="the <path> can be one or more file or folder")

    args = parser.parse_args()

    qApp = QtApp(sys.argv)
    try:
    convert_to(args.path, args.format, args.abort)
    print("covert over")
    except Exception as e:
    print(e)
    finally:
    # ubuntu
    # apt install psmisc
    print("kill all wpp")
    subprocess.call("killall -9 wpp", shell=True)


    if __name__ == "__main__":
    main()

    转换pdf

    1
    python convert.py -f pdf input.docx

    问题

    • libQt5Core.so.5: cannot open shared object file
    1
    2
    apt-get install libqt5core5a
    strip --remove-section=.note.ABI-tag /lib/x86_64-linux-gnu/libQt5Core.so.5
    • ImportError: /usr/lib/office6/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found (required by /usr/lib/libQt5Core.so.5)
    1
    2
    sudo rm /usr/lib/office6/libstdc++.so.6 
    sudo ln -s /usr/lib64/libstdc++.so.6 /usr/lib/office6/libstdc++.so.6

    openjdk8

    1
    2
    apt-get update
    apt-get install openjdk-8-jdk

    docker打包

    1
    docker commit -a "cong.zheng" -m "wps" b1f0d35fa596 wps-office:v1

    Dockerfile

    1
    2
    3
    4
    5
    6
    FROM congco/wps-office:v1.3.2

    RUN mkdir -p /apps
    WORKDIR /apps
    COPY target/*.jar /apps/
    COPY ./new.desktop /etc/xdg/autostart/

    new.desktop

    1
    2
    3
    4
    5
    [Desktop Entry]
    Version=1.0.0
    Name=new-doc
    Exec=xfce4-terminal -e="java -jar /apps/*.jar" # 使用terminal启动java服务
    Type=Application

    docker-compose

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    version: "3"

    services:
    new-doc01:
    container_name: new-doc-ccp01
    image: images.taimei.com/middle/new-doc-ccp:v1.0.0
    restart: always
    volumes:
    - /data/01/webapps:/data/webapps
    ## 禁止wps在无网络环境下请求DNS解析联网
    - /data/resolv.conf:/etc/resolv.conf:ro


    new-doc02:
    container_name: new-doc-ccp02
    image: congco/new-doc-ccp:v1.0.0
    restart: always
    volumes:
    - /data/012webapps:/data/webapps
    - /data/resolv.conf:/etc/resolv.conf:ro

    参考资料

    RUN ON SERVER


    镜像地址

    1
    docker push congco/wps-office:tagname

    制作镜像

    1
    2
    # 基础镜像为Ubuntu18.04LTS
    docker run --rm -it --name ubuntu-1804 ubuntu:18.04 bash

    更换国内源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse

    # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
    # # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse

    deb http://security.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse
    # deb-src http://security.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse

    # 预发布软件源,不建议启用
    # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
    # # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

    制作镜像

    • 安装wps
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #下载wps,可以自行替换版本
    # https://wps-linux-personal.wpscdn.cn/wps/download/ep/Linux2019/11698/wps-office_11.1.0.11698_amd64.deb
    wget -c https://wps-linux-personal.wpscdn.cn/wps/download/ep/Linux2019/10976/wps-office_11.1.0.10976_amd64.deb

    # 依赖
    apt update
    apt install libglu1-mesa bsdmainutils qt5-default xdg-utils
    # 安装
    dpkg -i wps-office_11.1.0.10976_amd64.deb
    • 安装字体

    https://github.com/qbmzc/wps-font-symbols

    1
    2
    3
    4
    5
    6
    7
    8
    wget https://github.com/qbmzc/wps-font-symbols/archive/refs/heads/master.zip
    apt install unzip
    unzip master.zip
    #拷贝字体到 usr/share/fonts
    cp -r ./wps-font-symbols /usr/share/fonts/


    fc-cache -vf
    • 安装python环境
    1
    2
    3
    4
    5
    6
    apt update
    # python3-lxml libxslt.so.1
    apt install python3 python3-pip python3-lxml

    # 安装pywpsrpc
    pip3 install pywpsrpc -i https://pypi.tuna.tsinghua.edu.cn/simple

    文档互转

    Run On Server

    1
    2
    #模拟x环境
    apt install xserver-xorg-video-dummy
    • dummy.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Section "Monitor"
    Identifier "dummy_monitor"
    HorizSync 28.0-80.0
    VertRefresh 48.0-75.0
    Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118
    EndSection

    Section "Device"
    Identifier "dummy_card"
    VideoRam 256000
    Driver "dummy"
    EndSection

    Section "Screen"
    Identifier "dummy_screen"
    Device "dummy_card"
    Monitor "dummy_monitor"
    SubSection "Display"
    EndSubSection
    EndSection

    Now start the Xorg (with root):

    1
    2
    # 启动x服务
    X :0 -config dummy.conf
    1
    2
    # 设置环境变量
    export DISPLAY=:0

    EULA

    1
    2
    3
     vim /root/.config/Kingsoft/Office.conf
    # 末尾添加
    common\AcceptedEULA=true

    转换pdf

    1
    python convert.py -f pdf input.docx

    问题

    1. 转换卡顿问题或超时

    本地部署一般为局域网访问,不开通外网,wps有外网连接请求,在没网的环境下会导致转换过慢,甚至会导致转换超时失败。

    1
    2
    3
    # 可使用tcpdump抓包分析

    tcpdump -i eth0 -nt -s 500 port domain

    解决方案

    • 将resolv.conf中的DNS解析服务器设置为空
    • docker中可以挂载一个空文件映射到/etc/resolv.conf
    • /etc/hosts 添加以下内容(由于有些部署方式会替换容器host,这里没有在容器内修改,可以在配置中添加主机别名)
    1
    2
    127.0.0.1 s1.vip.wpscdn.cn
    127.0.0.1 dw-online.ksosoft.com
    1. libQt5Core.so.5: cannot open shared object file
    1
    2
    apt-get install libqt5core5a
    strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    1. ImportError: /usr/lib/office6/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found (required by
      /usr/lib/libQt5Core.so.5)
    1
    2
    sudo rm /usr/lib/office6/libstdc++.so.6 
    sudo ln -s /usr/lib64/libstdc++.so.6 /usr/lib/office6/libstdc++.so.6
    1. et转换失败 error: libltdl.so.7: cannot open shared object file: No such file or directory
    1
    2
    3
    4
    5
    # dlopen /opt/kingsoft/wps-office/office6/libetmain.so failed , error: libltdl.so.7: cannot open shared object file: No such file or directory
    # Convert failed:
    # Details: Can't get the application
    # ErrCode: 0x80000008
    apt install libltdl7

    使用示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    FROM images.taimei.com/middle/wps-office:v2.0.4
    MAINTAINER congco
    ARG QUEUE=doc_convert_test
    ENV QUEUE $QUEUE
    WORKDIR /k8sapps
    COPY *.py /opt/
    COPY target/new-doc-convert-0.0.1-SNAPSHOT.jar /k8sapps/
    #RUN echo "java -jar /k8sapps/new-doc-convert-0.0.1-SNAPSHOT.jar" >> /root/.bashrc
    #COPY ./new.desktop /etc/xdg/autostart/
    #RUN echo "Exec=xfce4-terminal -e='java -Dspring.profiles.active=${PROFILES_ACTIVE} -Dqueue=${QUEUE} -jar /k8sapps/new-doc-convert-0.0.1-SNAPSHOT.jar '" >> /etc/xdg/autostart/new.desktop
    COPY start.sh /opt/start.sh
    RUN chmod +x /opt/start.sh
    ENV DISPLAY :0
    ENTRYPOINT ["/opt/start.sh"]

    • start.sh
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #! /bin/bash

    echo "start X server"

    nohup X :0 -config /etc/dummy.conf > /dev/null 2>&1 &
    echo "X server start successful!"
    echo "start java server"
    #python3 /opt/convert.py a.md -f pdf
    # CMD ["sh", "-c", "java ${APM_SRV_AGENT_OPTIONS} ${JAVA_OPTS} -jar /k8sapps/hls-1.0.0-SNAPSHOT.jar"]
    java ${APM_SRV_AGENT_OPTIONS} ${JAVA_OPTS} -Dqueue=${QUEUE} -jar /k8sapps/new-doc-convert-0.0.1-SNAPSHOT.jar