当从R调用时,Libreoffice给出"应用程序错误"

Ral*_*ner 8 r libreoffice docker

在docker容器内我试图使用LibreOffice将XLSX文件转换为PDF.相关命令在命令行上工作,但在从R调用时失败并显示"Application Error".我使用此命令Dockerfile添加一些(根据我的经验任意)XLSX文件:

FROM rocker/r-ver:3.4.3

RUN apt-get update \
 && apt-get install --yes --no-install-recommends \
    default-jre-headless libreoffice-calc \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/* \
 && echo /usr/lib/libreoffice/program > /etc/ld.so.conf.d/libreoffice.conf \
 && ldconfig

COPY foo.xlsx /tmp
Run Code Online (Sandbox Code Playgroud)

(诀窍ldconfig来自 R中系统函数的共享库问题.)

在命令行上,我可以将XLSX文件转换为PDF:

root@b395caeba33b:/# loffice --headless --convert-to pdf /tmp/foo.xlsx 
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
Run Code Online (Sandbox Code Playgroud)

然而,这从R失败:

> system("loffice --version")
LibreOffice 5.2.7.2 20m0(Build:2)

> system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
Application Error
Run Code Online (Sandbox Code Playgroud)

如果我改变从基本图像rocker/r-ver:3.4.3rocker/r-base它使用- [R 3.4.4和Debian测试/ SID结果的变化仅轻微:

> system("loffice --version")
LibreOffice 6.0.2.1.0 00m0(Build:1)

> system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
Application Error
Run Code Online (Sandbox Code Playgroud)

当从R调用时,如何让LibreOffice将XLSX文件转换为PDF?

Ral*_*ner 1

我找到了解决方法,但我仍然对正确的解释感兴趣。这是我发现的:

  • 使用选项启动 docker 容器--security-opt seccomp:unconfined并安装strace
  • R通话内

    system("strace -f -o R.trace loffice --headless --convert-to pdf /tmp/foo.xlsx")
    
    Run Code Online (Sandbox Code Playgroud)
  • 生成的跟踪文件显示加载错误libsal_textenclo.so。奇怪的是,/usr/lib/x86_64-linux-gnu尽管它ldconfig知道在哪里可以找到它,但它仍然在搜索该库:

    root@1519f52c05e0:/# grep libsal R.trace 
    257   open("/usr/lib/x86_64-linux-gnu/libsal_textenclo.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    root@1519f52c05e0:/# ldconfig -p | grep libsal
        libsal_textenclo.so (libc6,x86-64) => /usr/lib/libreoffice/program/libsal_textenclo.so
    
    Run Code Online (Sandbox Code Playgroud)
  • 设置LD_LIBRARY_PATH为包含并不能解决/usr/lib/libreoffice/program问题。

    root@4a235dfa08e3:~# export LD_LIBRARY_PATH=/usr/lib/libreoffice/program
    root@4a235dfa08e3:~# Rscript -e 'system("loffice --headless --convert-to pdf /tmp/foo.xlsx")'
    Application Error
    
    Run Code Online (Sandbox Code Playgroud)
  • LD_LIBRARY_PATH我当前的解决方法是在 R 会话中设置:

    > Sys.setenv(LD_LIBRARY_PATH="/usr/lib/libreoffice/program")
    > system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
    convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
    Overwriting: //foo.pdf
    
    Run Code Online (Sandbox Code Playgroud)