基于LibreOffice的MS Office文档格式转换

将Microsoft Office文件转换为其他格式的场景

在一些情况下,可能需要将Microsoft Office文件转换为其他格式:

  • 兼容性问题:与不同的办公软件或操作系统进行交互,可能需要将MS Office文件转换为更通用的格式。例如,如果要与没有安装Microsoft Office的人分享文档,将其转换为PDF格式可能更合适。
  • 归档和存档:将Office文件转换为更稳定、可持久保存的格式可以确保文件的长期保存和归档。某些文件格式(如PDF/A)专门用于长期存档目的,以确保文件内容的完整性和可访问性。
  • 数据提取:你可能只对文档中的特定数据或内容感兴趣。通过将Office文件转换为其他格式(如纯文本或CSV),可以更容易地提取所需的数据,并在其他应用程序中进行分析或处理。
  • 网页发布:如果要将MS Office文件发布到网页上,可能需要将其转换为HTML或其他网页友好的格式,以确保文件在网页上正确显示。

LibreOffice - 微软Office的开源替代

LibreOffice是一个免费、开源的办公套件,在某种程度上可以被视为微软Office的开源替代品。

  • LibreOffice Writer:对应于Microsoft Word。
  • LibreOffice Calc:对应于Microsoft Excel。
  • LibreOffice Impress:对应于Microsoft PowerPoint。

alt text

LibreOffice支持的转换格式

LibreOffice支持广泛的转换格式。具体请参考如下的表格:

Format FamilyFrom (any of)To (any of)
Text *.odt    OpenDocument Text
*.ott    OpenDocument Text Template
*.sxw    OpenOffice.org 1.0 Text
*.rtf    Rich Text Format
*.doc    Microsoft Word
*.docx   Microsoft Word XML
*.wpd    WordPerfect
*.txt    Plain Text
*.html   HTML
*.pdf    Portable Document Format
*.odt    OpenDocument Text
*.ott    OpenDocument Text Template
*.sxw    OpenOffice.org 1.0 Text
*.rtf    Rich Text Format
*.doc    Microsoft Word
*.docx   Microsoft Word XML
*.txt    Plain Text
*.html   HTML
*.wiki   MediaWiki wikitext
Spreadsheet *.ods    OpenDocument Spreadsheet
*.ots    OpenDocument Spreadsheet Template
*.sxc    OpenOffice.org 1.0 Spreadsheet
*.xls    Microsoft Excel
*.xlsx   Microsoft Excel XML
*.csv    Comma-Separated Values
*.tsv    Tab-Separated Values
*.pdf    Portable Document Format
*.ods    OpenDocument Spreadsheet
*.ots    OpenDocument Spreadsheet Template
*.sxc    OpenOffice.org 1.0 Spreadsheet
*.xls    Microsoft Excel
*.xlsx   Microsoft Excel XML
*.csv    Comma-Separated Values
*.tsv    Tab-Separated Values
*.html   HTML
Presentation *.odp    OpenDocument Presentation
*.otp    OpenDocument Presentation Template
*.sxi    OpenOffice.org 1.0 Presentation
*.ppt    Microsoft PowerPoint
*.pptx   Microsoft PowerPoint XML
*.pdf    Portable Document Format
*.swf    Macromedia Flash
*.odp    OpenDocument Presentation
*.otp    OpenDocument Presentation Template
*.sxi    OpenOffice.org 1.0 Presentation
*.ppt    Microsoft PowerPoint
*.pptx   Microsoft PowerPoint XML
*.html   HTML
Drawing *.odg    OpenDocument Drawing
*.otg    OpenDocument Drawing Template
*.svg    Scalable Vector Graphics
*.swf    Macromedia Flash

LibreOffice的headless模式

与常见的Chromium的headless模式类似,LibreOffice也提供headless模式。

  • 没有图形用户界面(GUI):无论是LibreOffice的headless模式还是Chromium的headless模式,都在没有GUI的情况下运行,不会显示可见的窗口或用户界面。
  • 命令行接口(CLI)控制:通过命令行接口进行控制和操作。可以在命令行中使用特定的命令和参数来执行相应的任务和操作。
  • 自动化和批处理:LibreOffice的headless模式和Chromium的headless模式都适用于自动化和批处理任务。
  • 服务器环境中的应用:适用于在服务器环境中使用。

这就给在服务端自动化进行文档类型转换提供了很大的便利。

资源池管理与容器化 - JodConverter

JodConverter是一个用于将Office文档转换为其他格式的Java库。它支持与LibreOffice(也可以是OpenOffice)进行集成。

我们可以选择自己直接与headless的LibreOffice直接通信来完成文档格式转换,不过由JodConverter来代劳的好处是很明显的:

  • 资源池化
  • 容器化

JODConverter 的进程管理器(Process Manager)在资源池内维护 LibreOffice 进程。
将 LibreOffice 进程保持在资源池内,可以避免每次进行文档转换时都需要启动和终止 LibreOffice 进程的开销。
它可以检测到进程的健康状态,例如进程异常退出或崩溃,然后采取相应的措施,如重新启动进程。

JODConverter 还提供一个基于Debian的基础docker image,其中已经包含了LibreOffice。

我们的调用JODConverter的Java应用只需要基于该镜像build出来就好。

alt text

MS Office存量文件的兼容性 - 字体的开源替代

alt text

上面这张图左侧是原版的PPT,右侧是用JOD + LibreOffice转换出来的PDF。

可以看到右侧转换出PDF,文字之间出现了互相交叉重叠的现象,整个样式都乱掉了。
这其实并不是JOD或者是LibreOffice的bug。

而是由于左侧的PPT当中使用了一些微软的商用字体。
而LibreOffice运行在docker里面,它是拿不到这些微软的商用字体的,我们也不应该把有商用版权的字体置入docker image中。

这时我们可以使用一些开源的字体来代替微软的商用字体

下图来自于LibreOffice的一篇博客: https://blog.documentfoundation.org/blog/2020/09/08/libreoffice-tt-replacing-microsoft-fonts/

font

LibreOffice提供了一个Font Replacement Table的功能。

左侧Font列是商用字体,右侧Replace with列是开源字体。
例如:当LibreOffice见到一个ppt文件内的某段文字使用了Arial字体时,就会自动用Arimo字体去渲染这段文字。
这样,既能够尽量保持视觉效果的一致性,也避免使用商用字体。

下图是使用了开源字体替代后的转换效果,右侧的PDF和左侧的PPT视觉差异已经不太大了。
alt text

作为一个LibreOffice桌面应用的使用者可以按照上述说明来做配置,从而最大程度的去兼容微软的商用字体。
而当我们使用headless模式时该如何做出等效的配置呢?

LibreOffice - User Profile

上面提到的配置项,会被保存在LibreOffice User Profile内,在不同的OS内保存的路径为:

1
2
3
4
5
Windows
%APPDATA%\libreoffice\4\user (LibreOffice 4 and above)

GNU/Linux
/home/<user name>/.config/libreoffice/4/user (LibreOffice 4 and above)

我们可以把开源字体文件以及保存下来的配置文件内置入docker image内。
并通过JOD指定启动LibreOffice时的参数,让headless模式下运行的LibreOffice加载到正确的配置文件,进而也能达成上图所示一样转换的效果。

如下Dockerfile示例中把开源字体和配置文件copy进Docker image

1
2
3
4
5
6
7
# support more fonts
COPY cjk-fonts/* /usr/share/fonts/cjk/
COPY condensed-fonts/* /usr/share/fonts/condensed/
COPY ms-sub-fonts/* /usr/share/fonts/ms-sub-fonts/

# add user profile config files
COPY ./profile/LibreOffice/4/user /tmp/jodconverter/user

如下示例中指定template-profile-dir

1
2
3
4
5
jodconverter:
local:
enabled: true
port-numbers: 2002,2003
template-profile-dir: /tmp/jodconverter

这样可以确保JODConverter在启动LibreOffice进程的时候可以明确地告诉LibreOffice去加载哪一份配置文件。

Links

JODConverter Wiki

jodconverter-runtime docker基础镜像

LibreOffice PDF转换支持的命令行参数

宽度过大的Excel转PDF的问题

微软字体兼容性问题

LibreOffice User Profile默认路径

把自定义的字体与User Profile加入Docker Image

给JODConverter指定User Profile路径