Skip to content

[18.0][attachment_preview] Add Office format preview via LibreOffice conversion#603

Open
dnplkndll wants to merge 3 commits into
OCA:18.0from
ledoent:18.0-add-office-preview
Open

[18.0][attachment_preview] Add Office format preview via LibreOffice conversion#603
dnplkndll wants to merge 3 commits into
OCA:18.0from
ledoent:18.0-add-office-preview

Conversation

@dnplkndll

Copy link
Copy Markdown
Contributor

Summary

Extends attachment_preview to support DOCX, XLSX, PPTX, DOC, XLS, PPT, and ODG preview in addition to the existing PDF + ODF support.

How it works

  • New HTTP endpoint: GET /attachment_preview/office_to_pdf?model=&field=&id=&filename=
  • On request, converts the binary field content to PDF using LibreOffice headless (libreoffice --headless --convert-to pdf)
  • Returns the PDF to ViewerJS for in-browser rendering
  • Gracefully returns HTTP 503 if LibreOffice is not installed — no preview button appears for Office files on deployments without LibreOffice

Changes

File Change
controllers/main.py New LibreOffice conversion HTTP controller
static/src/js/utils.esm.js OFFICE_EXTENSIONS added to canPreview(); getUrl() routes Office extensions through conversion endpoint with ?type=pdf for ViewerJS
static/src/js/web_views/fields/binary_field.esm.js Passes filename to showPreview() so conversion endpoint receives correct extension

Requirements

  • LibreOffice must be installed in the Odoo environment for Office preview to function
  • No new Python dependencies (uses stdlib subprocess, tempfile)
  • Existing PDF + ODF preview unaffected

Test plan

  • Upload a .docx file to a record with a binary field → preview button (↗) appears
  • Click preview → ViewerJS opens with converted PDF content
  • Upload a .xlsx / .pptx → same behavior
  • On an Odoo instance without LibreOffice → preview button does not appear for Office files (503 response causes button to stay hidden)
  • Existing PDF preview unaffected
  • Existing ODS/ODT preview unaffected

🤖 Generated with Claude Code

dnplkndll added a commit to ledoent/knowledge that referenced this pull request Mar 30, 2026
…ffice

Extends attachment_preview to support DOCX, XLSX, PPTX, DOC, XLS, PPT,
and ODG in addition to the existing PDF + ODF format support.

New endpoint: GET /attachment_preview/office_to_pdf
  Accepts ?model=<model>&field=<field>&id=<id>&filename=<name>
  Converts the binary field content to PDF using LibreOffice headless,
  then streams the PDF to ViewerJS for in-browser rendering.
  Returns HTTP 503 gracefully if LibreOffice is not installed.

Changes:
- controllers/main.py: new HTTP controller with LibreOffice conversion
- utils.esm.js: OFFICE_EXTENSIONS added to canPreview(); getUrl() routes
  Office files to the conversion endpoint
- binary_field.esm.js: passes filename for correct extension detection
- tests: controller unit tests covering success, FileNotFoundError,
  TimeoutExpired, and non-zero exit code paths

Closes OCA#603
@dnplkndll dnplkndll force-pushed the 18.0-add-office-preview branch from 8702c2f to d9a4a06 Compare March 30, 2026 15:30
dnplkndll added a commit to ledoent/knowledge that referenced this pull request Jun 19, 2026
…ffice

Extends attachment_preview to support DOCX, XLSX, PPTX, DOC, XLS, PPT,
and ODG in addition to the existing PDF + ODF format support.

New endpoint: GET /attachment_preview/office_to_pdf
  Accepts ?model=<model>&field=<field>&id=<id>&filename=<name>
  Converts the binary field content to PDF using LibreOffice headless,
  then streams the PDF to ViewerJS for in-browser rendering.
  Returns HTTP 503 gracefully if LibreOffice is not installed.

Changes:
- controllers/main.py: new HTTP controller with LibreOffice conversion
- utils.esm.js: OFFICE_EXTENSIONS added to canPreview(); getUrl() routes
  Office files to the conversion endpoint
- binary_field.esm.js: passes filename for correct extension detection
- tests: controller unit tests covering success, FileNotFoundError,
  TimeoutExpired, and non-zero exit code paths

Closes OCA#603
@dnplkndll dnplkndll force-pushed the 18.0-add-office-preview branch from d9a4a06 to 375b593 Compare June 19, 2026 18:30
@OCA-git-bot OCA-git-bot added series:18.0 mod:attachment_preview Module attachment_preview labels Jun 19, 2026
dnplkndll added a commit to ledoent/knowledge that referenced this pull request Jun 19, 2026
…ffice

Extends attachment_preview to support DOCX, XLSX, PPTX, DOC, XLS, PPT,
and ODG in addition to the existing PDF + ODF format support.

New endpoint: GET /attachment_preview/office_to_pdf
  Accepts ?model=<model>&field=<field>&id=<id>&filename=<name>
  Converts the binary field content to PDF using LibreOffice headless,
  then streams the PDF to ViewerJS for in-browser rendering.
  Returns HTTP 503 gracefully if LibreOffice is not installed.

Changes:
- controllers/main.py: new HTTP controller with LibreOffice conversion
- utils.esm.js: OFFICE_EXTENSIONS added to canPreview(); getUrl() routes
  Office files to the conversion endpoint
- binary_field.esm.js: passes filename for correct extension detection
- tests: controller unit tests covering success, FileNotFoundError,
  TimeoutExpired, and non-zero exit code paths

Closes OCA#603
@dnplkndll dnplkndll force-pushed the 18.0-add-office-preview branch from 375b593 to ba32cd7 Compare June 19, 2026 18:30
…ffice

Extends attachment_preview to support DOCX, XLSX, PPTX, DOC, XLS, PPT,
and ODG in addition to the existing PDF + ODF format support.

New endpoint: GET /attachment_preview/office_to_pdf
  Accepts ?model=<model>&field=<field>&id=<id>&filename=<name>
  Converts the binary field content to PDF using LibreOffice headless,
  then streams the PDF to ViewerJS for in-browser rendering.
  Returns HTTP 503 gracefully if LibreOffice is not installed.

Changes:
- controllers/main.py: new HTTP controller with LibreOffice conversion
- utils.esm.js: OFFICE_EXTENSIONS added to canPreview(); getUrl() routes
  Office files to the conversion endpoint
- binary_field.esm.js: passes filename for correct extension detection
- tests: controller unit tests covering success, FileNotFoundError,
  TimeoutExpired, and non-zero exit code paths

Closes OCA#603
@dnplkndll dnplkndll force-pushed the 18.0-add-office-preview branch from ba32cd7 to 136409c Compare June 20, 2026 13:50
@pedrobaeza

Copy link
Copy Markdown
Member

Why not integrating viewerjs directly into usual Odoo preview instead of having another preview mechanism like attachment_preview?

…onversion

Render office previews through Odoo's native PDF.js viewer instead of a bundled
ViewerJS widget (addresses the "don't ship a parallel preview mechanism" review
point). All office formats — ODF *and* OOXML — are converted to PDF server-side
via LibreOffice and rendered with /web/static/lib/pdfjs, the same viewer core's
FileViewer uses. The bundled ViewerJS library (21 files) is removed.

Why conversion is required: ViewerJS renders only ODF + PDF and Odoo's native
viewer renders no office formats, so previewing XLSX/PPTX/DOCX needs a
server-side conversion regardless of the display widget.

Harden the /attachment_preview/office_to_pdf controller:
- validate the requested field exists and is Binary (no arbitrary attribute read)
- exists() + record-level check_access("read")
- reject documents over a size cap (HTTP 413)
- isolate each LibreOffice run with -env:UserInstallation to avoid the shared
  profile-lock collision under concurrency
- cache converted PDFs by content checksum under the data_dir (best-effort)

Tests: add coverage for ODF acceptance, non-binary/unknown field rejection,
oversize rejection, and the isolated-profile flag. Verified real xlsx/ods -> PDF
conversion + 3 concurrent conversions on Odoo 18 with LibreOffice.
…escription

DESCRIPTION.md still described the old ViewerJS approach; rewrite it for the
native PDF.js + LibreOffice-conversion design. INSTALL.md now states the hard
LibreOffice system dependency that office preview needs — it is not in the
standard Odoo image, so without it the office endpoint returns HTTP 503 and only
PDF preview works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:attachment_preview Module attachment_preview series:18.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants