nowo-tech / word-to-pdf-bundle
Symfony bundle: convert Microsoft Word (.docx/.doc) to PDF via LibreOffice Writer (soffice) with named profiles and runtime dependency checks.
Package info
github.com/nowo-tech/WordToPdfBundle
Type:symfony-bundle
pkg:composer/nowo-tech/word-to-pdf-bundle
Requires
- php: >=8.2 <8.6
- ext-fileinfo: *
- league/flysystem: ^3.16
- symfony/config: ^7.0 || ^8.0
- symfony/console: ^7.0 || ^8.0
- symfony/dependency-injection: ^7.0 || ^8.0
- symfony/http-foundation: ^7.0 || ^8.0
- symfony/http-kernel: ^7.0 || ^8.0
- symfony/process: ^7.0 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- nowo-tech/phpstan-frankenphp: ^1.0
- phpstan/extension-installer: ^1.0
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^11.0
- rector/rector: ^2.0
- symfony/framework-bundle: ^7.0 || ^8.0
- symfony/yaml: ^7.0 || ^8.0
Suggests
- nowo-tech/html-to-word-bundle: Optional: build .docx from HTML before converting to PDF.
- nowo-tech/word-template-bundle: Optional: fill .docx templates before converting to PDF.
README
Found this useful? Install from Packagist (
composer require nowo-tech/word-to-pdf-bundle) and consider starring WordToPdfBundle on GitHub.
FrankenPHP demos: runtime is selected with FRANKENPHP_MODE (worker default, or classic for per-request PHP / hot-reload). See docs/DEMO-FRANKENPHP.md.
Symfony bundle that converts Microsoft Word (.docx / .doc) to PDF using LibreOffice Writer (soffice headless) for print-quality layout fidelity:
- named YAML profiles + default profile + deep merge with per-call options, or
convertWithInlineProfile(); - batch conversion via
convertMany()withPdfNaming(keep / prefix / suffix / surround / fixed / callback, or path ⇒ filename map); - runtime check that LibreOffice Writer is installed (
nowo:word-to-pdf:check); fails with install hints if missing; - works under PHP-FPM and FrankenPHP (Symfony Process /
proc_open); - Symfony-friendly export: streamed/binary responses, local path, optional Flysystem. This bundle does not fill Word templates (see WordTemplateBundle), convert HTML to Word (see HtmlToWordBundle), or use DomPDF (DomPDF cannot preserve Word styles).
This bundle is FrankenPHP worker mode friendly.
Quick start
composer require nowo-tech/word-to-pdf-bundle php bin/console nowo:word-to-pdf:check
# config/packages/nowo_word_to_pdf.yaml nowo_word_to_pdf: default_profile: default profiles: default: timeout: 180 export: filename: document.pdf
Prefer the shared Nowo env (demos and multi-bundle apps):
timeout: '%env(int:PROCESS_TIMEOUT)%' # PROCESS_TIMEOUT=180 in .env
use Nowo\WordToPdfBundle\Converter\WordToPdfConverterInterface; use Nowo\WordToPdfBundle\Export\ExporterInterface; use Nowo\WordToPdfBundle\Naming\PdfNaming; public function download(WordToPdfConverterInterface $converter, ExporterInterface $exporter): Response { $pdf = $converter->convert('/path/to/contract.docx'); // Batch: $converter->convertMany([$pathA, $pathB], PdfNaming::suffix(' [converted]')); return $exporter->toBinaryResponse($pdf); }
System requirement
LibreOffice Writer must be installed on the host / container (Composer cannot install it):
# Debian / Ubuntu sudo apt-get install -y libreoffice-writer # Alpine apk add libreoffice # Fedora / RHEL sudo dnf install -y libreoffice-writer
Verify:
php bin/console nowo:word-to-pdf:check
Development
make up make qa make release-check
FrankenPHP worker mode
FrankenPHP worker mode: Supported (tested with LibreOffice conversion under FrankenPHP).
The demo runs under FrankenPHP. Conversion uses Symfony Process with a hard timeout (and idle timeout); on expiry the runner stops the process tree so workers are not left with orphaned LibreOffice children (REQ-RUNTIME-001). Align PHP / Caddy deadlines above the profile timeout.
Demos use FRANKENPHP_MODE (worker by default, or classic) on PHP 8.5 — see docs/DEMO-FRANKENPHP.md. Change mode in .env and recreate containers (docker compose up -d); no image rebuild.
cd demo/symfony8 && cp .env.example .env && make up # Symfony 8, port 8022
Documentation
- Installation
- Configuration
- Usage
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
Additional documentation
- GitHub Actions CI requirements
- FrankenPHP / Docker demo —
demo/symfony8(seedemo/README.md)
Tests and coverage
| Scope | Detail |
|---|---|
| PHPUnit | composer test — unit + integration (@group libreoffice skipped when soffice is absent). |
| PHP lines | composer coverage-check enforces 100% (PCOV). Latest measurement: PHP: 100%. |
| TS/JS | N/A (no frontend assets in this bundle). |
composer test
composer coverage-check
