在CentOS服务器上安装unoserver

這是2023年LibreOffice科技降世紀曆的第七篇文章。

一個unoserver是指

LibreOffice具有批量启动并转换文档文件格式的功能。

$ libreoffice --headless --convert-to pdf sample.odt

作为可能的输入格式,除了LibreOffice的本机OpenDocument格式外,还包括几乎所有LibreOffice可以读取的常见文档格式(如DOCX)和图像格式(如PNG)。建议查看维基百科的文章以获取更详细信息。

在单次转换任务中,这种方法是没有问题的。但是,作为提供转换服务的服务器用途,每次都启动LibreOffice会产生一定的成本。为了减少启动开销,unoserver是一个工具,可以让LibreOffice持续运行。当在服务器上启动unoserver,客户端机器可以使用unoconvert命令进行转换。

我們將按照以下步驟,盡可能簡單地解釋如何在CentOS上安裝並運行unoserver。我們在CentOS Stream 8(以及Oracle Linux 8.8)和CentOS Stream 9(此處省略「Stream」)(皆用作伺服器安裝)上進行了驗證。請注意,每個套件的可用性和版本號是根據驗證時的情況而定。

还有一个由同一作者开发的用于相同目的的工具叫做unoconv,在这里不予考虑,因为该工具已经过时,并且已经超过两年没有更新(我们已经确认它可以正常运行)。

准备Python

CentOS 8 —- 安装Python39

CentOS 8的platform-python版本为3.6.8,但在使用pip安装unoserver时会出现以下错误。尽管unoserver源代码中的pyproject.toml文件里写明了requires-python = “>= 3.8″,但为什么会显示’>= 3.7’,我不知道。

# /usr/libexec/platform-python -m pip install unoserver
...
unoserver requires Python '>= 3.7' but the running Python is 3.6.8

如果从官方网站下载并安装最新的LibreOffice,它会附带Python 3.8,因此您可以使用它来满足条件。但是,这个Python版本没有pip和ensurepip,因此需要获取get-pip.py并安装pip等,有点不方便。

考虑到可能还存在其他需要新版本Python的情况,为了与CentOS 9搭配,我们将在此安装Python 3.9,其将与默认仓库一同安装pip3。尽管3.11也是可行的,但尚未经过验证。

# dnf install -y python39

顺便提一下,最新的LibreOffice附带的Python中安装pip,并使用它安装某些包时,脚本的Shebang指定了program/python.bin。然而,这个二进制文件没有预先设置所需的路径,所以无法直接启动脚本。你需要修改脚本以指定program/python(sh脚本),或者在脚本启动之前设置环境变量来包装它。在更新LibreOffice版本时也需要注意。

其实,在unoserver的情况下,由于必须进行环境变量的设置,所以这个部分的工作量并没有太大差别。但如果通过systemd启动,可以在配置文件中完成环境变量的设置。

CentOS 9 — 安装pip

CentOS 8 的 platform-python 版本是 3.9.18,所以满足条件。然而,pip 尚未安装,如果还没有安装,需要先安装。

# dnf install -y python3-pip

准备LibreOffice

從標準的AppStream安裝LibreOffice。

如果按照下述方式进行操作,将在CentOS 8上安装LibreOffice 6.4.7.2,在CentOS 9上安装LibreOffice 7.1.8.1。然而,当使用LibreOffice 6.4进行转换时,可能会出现无法控制的情况,导致系统崩溃并可能成为拒绝服务攻击(DoS)。虽然在7系列中可能存在类似情况,但目前尚未发现。因此,建议在CentOS 8上跳过以下步骤并安装最新的LibreOffice。

# dnf install -y libreoffice

不需要安装 libreoffice-langpack-ja(但安装也没有问题)。

在CentOS 8上,libreoffice-pyuno的相关文件被安装在platform-python的site-packages目录中。由于CentOS 8使用的是Python 3.9而不是platform-python,因此需要将这些文件复制到Python 3.9的位置。

# cp /usr/lib64/python3.6/site-packages/{officehelper,uno,unohelper}.py /usr/lib64/python3.9/site-packages

安装最新版本的LibreOffice

如果您想使用最新的LibreOffice(目前版本为7.6.3.2),请在官方下载网站上选择Linux(64位)(rpm)作为操作系统进行下载。无需额外下载语言相关的文件。

将其展开并安装RPMS目录中的rpm文件。

# dnf install -y RPMS/*.rpm

此外,看起来LibreOffice的启动需要以下库文件,所以如果还没有的话,先安装好。

# ldd /opt/libreoffice7.6/program/{oosplash,soffice.bin} | grep 'not found'
	libXinerama.so.1 => not found
	libcups.so.2 => not found
# dnf install -y libXinerama cups-libs

字体准备

安装日语字体

如果在CentOS 9上安装了日语环境(langpacks-ja)或安装了libreoffice-langpack-ja,那么Noto系列CJK字体也会一并安装。

除此之外的情况,我们需要明确地按照以下方式安装。

# dnf install -y google-noto-sans-cjk-ttc-fonts google-noto-serif-cjk-ttc-fonts

另外,您也可以從官方發布的Google網站上下載並安裝Noto字體,但需要注意的是,由於其斷爲不同的字重變化,所以請小心。除了Noto系列字體之外,如果有可能在原始文檔中使用其他字體,則建議您在需要時將其安裝在/usr/share/fonts目錄下。BIZ UD系列和IPA系列字體是代表性範例。

设置字体别名

在Windows和Office中配备的字体中,很多情况下是无法根据许可证进行使用的。在这种情况下,如果指定了想要使用的字体以及可用作替代的字体对应关系,就可以在不过多损害原本氛围的情况下进行转换。以下的fontconfig配置文件是我为自己的环境使用别名实现的一个例子。为了使其更易于阅读,应适当加入换行符,但由于太过冗长,我将每个字体都合并为一行。如果有包含英文字体和其他CJK字体的更完善的配置文件,我会很想要获取。

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <alias><family>BIZ UDGothic</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>BIZ UDゴシック</family> <accept><family>BIZ UDGothic</family></accept> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>BIZ UDMincho</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UD明朝</family> <accept><family>BIZ UDMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UDMincho Medium</family> <accept><family>BIZ UDMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UD明朝 Medium</family> <accept><family>BIZ UDMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UDPGothic</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>BIZ UDPゴシック</family> <accept><family>BIZ UDPGothic</family></accept> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>BIZ UDPMincho</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UDP明朝</family> <accept><family>BIZ UDPMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UDPMincho Medium</family> <accept><family>BIZ UDPMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>BIZ UDP明朝 Medium</family> <accept><family>BIZ UDPMincho</family></accept> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>MS Gothic</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>MS ゴシック</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>MS Mincho</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>MS 明朝</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>MS PGothic</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>MS Pゴシック</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>MS PMincho</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>MS P明朝</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>MS UI Gothic</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Meiryo UI</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Meiryo</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>メイリオ</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho NK-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 NK-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho NK-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 NK-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho NP-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 NP-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho NP-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 NP-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho N-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 N-B</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD Digi Kyokasho N-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>UD デジタル 教科書体 N-R</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic UI</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic UI Light</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic UI Semibold</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic UI Semilight</family> <default><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic</family> <default><family>Noto Sans CJK JP Light</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>游ゴシック</family> <default><family>Noto Sans CJK JP Light</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic Light</family> <default><family>Noto Sans CJK JP Thin</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>游ゴシック Light</family> <default><family>Noto Sans CJK JP Thin</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Gothic Medium</family> <default><family>Noto Sans CJK JP Medium</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>游ゴシック Medium</family> <default><family>Noto Sans CJK JP Medium</family><family>Noto Sans CJK JP</family></default></alias>
    <alias><family>Yu Mincho</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>游明朝</family> <default><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>Yu Mincho Demibold</family> <default><family>Noto Serif CJK JP SemiBold</family><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>游明朝 Demibold</family> <default><family>Noto Serif CJK JP SemiBold</family><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>Yu Mincho Light</family> <default><family>Noto Serif CJK JP Light</family><family>Noto Serif CJK JP</family></default></alias>
    <alias><family>游明朝 Light</family> <default><family>Noto Serif CJK JP Light</family><family>Noto Serif CJK JP</family></default></alias>
</fontconfig>

准备和启动unoserver。

安装Unoserver

unoserver可以通过使用pip3(在CentOS 9上也可使用pip命令)进行安装。虽然在root用户下执行会收到警告,但可执行脚本将安装在/usr/local/bin目录下,相关文件将安装在/usr/local/lib/python3.9/site-packages目录下,因此几乎不会与标准软件包发生冲突。

# pip3 install unoserver

端口的打开

默认情况下,Unoserver将在2003/TCP端口等待来自客户端的连接。由于没有身份验证,防火墙和监听地址的指定是唯一的壁垒。在原始的CentOS中,防火墙应该会阻止几乎所有端口,因此需要将此端口打开至必要范围。如果在NAT中或者其他地方要全部打开,可以按以下方式设置。如果2003/TCP端口被其他服务占用,则请选择适当的端口号,并在unoserver和unoconvert启动时使用–port选项进行指定。

# firewall-cmd --permanent --add-port 2003/tcp
# firewall-cmd --reload

除了2003/TCP之外,2002/TCP也在unoserver和LibreOffice服务器之间使用。然而,由于该通信仅限于服务器内部,如果没有特殊的原因,可以不做任何处理。

启动unoserver

为了将其作为systemd服务注册,创建一个新的配置文件。该配置文件被命名为/usr/lib/systemd/system/unoserver.service,但如果您是独特的服务,根据惯例,请将其放置在/etc/systemd/system中。

[Unit]
Description=Unoserver for document conversions
Documentation=https://github.com/unoconv/unoserver
After=network.target

[Service]
Type=simple
Environment="LC_ALL=ja_JP.UTF-8"
ExecStart=/usr/local/bin/unoserver --interface 0.0.0.0 --uno-interface 127.0.0.1
TimeoutStopSec=3

[Install]
WantedBy=multi-user.target

在设置文件中,我们希望将其作为外部服务提供,因此使用–interface选项指定为0.0.0.0,但如果要将IP地址限制为多个中的任何一个,我们需要进行指定(在这种情况下,可能最好使用After=network-online.target而不是After=network.target)。默认值是127.0.0.1。–uno-interface是用于unoserver和LibreOffice连接的接口,默认情况下是127.0.0.1,因此可以省略,但由于存在一个似乎是已报告的错误(Bug)导致默认值变为了通过–interface指定的值(因此我们要进行明确指定)。

另外,我们可以通过环境变量LC_ALL来设置在没有包含语言或字符编码信息的输入中,用于选择字体所需的默认设置。如果您在操作系统中已经选择了日文设置,则可能不需要这个设置。

另外,由于在CentOS 9中停止服务时可能会出现问题,所以我把TimeoutStopSec从默认的90秒改为3秒。

如果安装了最新版本的公式版LibreOffice,则需要进行以下环境变量设置:pyuno相关文件所在目录的环境变量设置、Uno Runtime环境的配置文件的环境变量设置、LibreOffice的执行命令名称的选项指定。即如下所示。

[Unit]
Description=Unoserver for document conversions
Documentation=https://github.com/unoconv/unoserver
After=network.target

[Service]
Type=simple
Environment="LC_ALL=ja_JP.UTF-8"
Environment="PYTHONPATH=/opt/libreoffice7.6/program"
Environment="URE_BOOTSTRAP=vnd.sun.star.pathname:/opt/libreoffice7.6/program/fundamentalrc"
ExecStart=/usr/local/bin/unoserver --executable libreoffice7.6 --interface 0.0.0.0 --uno-interface 127.0.0.1
TimeoutStopSec=3

[Install]
WantedBy=multi-user.target

我們將啟用並啟動 systemctl 服務。

# systemctl enable unoserver
# systemctl start unoserver

客户准备和执行

客户端不需要与服务器在同一台机器或操作系统上,因为可能存在各种情况,不一一详述。但如果在CentOS或Ubuntu上安装了适当版本的Python 3和pip,并提供给所有用户,那么请安装unoserver,与服务器端一样。

# pip3 install unoserver

只需一种选项,以下是对该句的中文本地化改写:“必要的是将/usr/local/bin/unoconvert(根据需要也可以包括unocompare)复制或链接到/usr/bin,或者在/usr/local/bin中设置PATH,或者通过指定完整路径来执行。”

执行转换的方法如下。

$ unoconvert --host SERVERIPADDRORNAME sample.docx sample.pdf

在测试目的或其他情况下,如果要在VirtualBox等虚拟机的guest machine上启动unoserver,并通过NAT+端口转发从host machine进行连接,有一点需要注意。当使用–host 127.0.0.1参数(或者省略该参数)时,即使指定–host-location remote,输出文件仍会在服务器端创建,这是一个已报告的bug。只有当–host设置为默认的127.0.0.1和localhost时,它才会被特别处理,因此仍然可以通过指定127.1等来绕过此问题。

最后

我解释了在安装CentOS时所需进行的各种准备工作和注意事项。尽管这是一个小工具,但由于操作系统的差异、Python的差异、LibreOffice的差异等,存在许多容易出错的地方,如果不一一解决这些问题就无法成功安装。希望我所提供的帮助对于那些无法享受这样的尝试和错误、或者没有太多时间投入的读者来说是有益的。

当需要明确除默认语言和编码以外的文本或CSV文件时,我对适当的过滤器指定方法并不十分清楚。

希望操作系统的安装过程更加简便,同时希望在OS的支持和未来版本更新中解决功能和文档不足的问题。

如果您在安装时遇到了问题,请在评论中告诉我们。

祝你愉快的转换生活!

以下是LibreOffice 6.4出现故障的文件示例:将HEIC文件的扩展名更改为JPG的情况,部分(可能是因为插入的图像等原因导致布局大幅变化的)Word文件。
广告
将在 10 秒后关闭
bannerAds