laravel-anydoc maintained by iammuttaqi
Laravel Anydoc
Convert Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, and PDF documents to clean GitHub-Flavored Markdown in Laravel — powered by Firecrawl anydoc, the Rust library that converts office documents to LLM-ready Markdown in single-digit milliseconds.
There is no PHP binding for anydoc, so this package drives its CLI through Symfony Process. The CLI ships as the npm package @firecrawl/anydoc; npx downloads the prebuilt binary on first use and caches it, so there is nothing else to install beyond Node.js.
Requirements
- PHP 8.1+
- Laravel 10, 11, 12 or 13
- Node.js 20+ (with
npxon PATH)
Installation
composer require iammuttaqi/laravel-anydoc
Optionally publish the config file:
php artisan vendor:publish --tag=anydoc-config
For a permanent install of the CLI (instead of going through npx on every call), run:
php artisan anydoc:install
Usage
use Muttaqi\Anydoc\Facades\Anydoc;
use Muttaqi\Anydoc\Support\Format;
// From a file path:
$markdown = Anydoc::toMarkdown('/path/to/report.docx');
// From an uploaded file:
$markdown = Anydoc::toMarkdown($request->file('document'));
// From bytes, with the format detected from the content:
$markdown = Anydoc::toMarkdownBytes($bytes);
// Or name it, which signature-less formats (CSV) need:
$markdown = Anydoc::toMarkdownBytes($bytes, Format::Csv);
// Format detection:
Anydoc::formatFromPath('report.odt'); // Format::Odt
Anydoc::formatFromExtension('.pptm'); // Format::Pptx
Anydoc::formatFromBytes($bytes); // Format::Docx, or null
Or via dependency injection:
use Muttaqi\Anydoc\Anydoc;
class DocumentController
{
public function show(Anydoc $anydoc, string $id)
{
return $anydoc->toMarkdown('/path/to/'.$id.'.pptx');
}
}
Supported formats
| Format | Extensions |
|---|---|
| Word | .doc, .docx, .docm |
| PowerPoint | .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm |
| Excel | .xls, .xlsx, .xlsm, .xlsb |
| OpenDocument | .odt, .ods, .odp |
| Rich Text | .rtf |
| EPUB | .epub |
| CSV | .csv |
.pdf |
The format is detected from the file content, not the extension, so mislabeled files still convert correctly. CSV has no content marker — pass it explicitly (or rely on the file extension).
Artisan commands
# Convert a single document
php artisan anydoc:convert report.docx
php artisan anydoc:convert slides.pptx --output=slides.md
php artisan anydoc:convert data.csv --format=csv --output=data.md
# Install the anydoc CLI globally
php artisan anydoc:install
Errors
A conversion only fails when no meaningful Markdown could come out of the file. Each failure is thrown as a typed exception, mirroring anydoc's own error variants:
| Exception | Meaning |
|---|---|
UnsupportedException |
Unknown format, or one that cannot be converted (an image-only PDF) |
MalformedException |
Structurally unusable document |
EncryptedException |
Encrypted or password-protected |
ResourceLimitException |
Crossed a fixed safety limit |
MissingPartException |
A part required for meaningful output is absent |
InvalidUsageException |
The CLI was invoked with bad arguments (should not happen) |
ConversionException |
Any other conversion failure |
BinaryNotFoundException |
Node/npx/the anydoc binary is not installed |
AnydocException |
Base class for all of the above |
use Muttaqi\Anydoc\Exceptions\AnydocException;
use Muttaqi\Anydoc\Exceptions\EncryptedException;
use Muttaqi\Anydoc\Exceptions\UnsupportedException;
try {
$markdown = Anydoc::toMarkdown($file);
} catch (EncryptedException|UnsupportedException $e) {
// No document comes out of these — record the file and move on.
report($e);
}
Configuration
Publish the config and adjust config/anydoc.php:
| Variable | Default | Description |
|---|---|---|
ANYDOC_USE_NPX |
true |
Use npx -y @firecrawl/anydoc instead of a fixed binary |
ANYDOC_BINARY |
anydoc |
Binary to call when ANYDOC_USE_NPX=false |
ANYDOC_NPX_PACKAGE |
@firecrawl/anydoc |
npm package providing the CLI |
ANYDOC_TIMEOUT |
60 |
Max seconds per conversion (seconds) |
ANYDOC_TEMP_DIR |
sys_get_temp_dir() |
Where temporary input files are written |
Windows
Symfony Process resolves npx through the shell-less PATH lookup, which can miss npx.cmd. If that happens, install the CLI and point the package at the full path:
npm install -g @firecrawl/anydoc
ANYDOC_USE_NPX=false
ANYDOC_BINARY=C:\path\to\npx.cmd
Notes
- Embedded images render as their alt text (Markdown cannot embed bytes); the raw bytes stay available on anydoc's document model, which the CLI does not expose.
- Scanned/image-only PDFs need OCR, which anydoc does not do — they fail as
UnsupportedException. Firecrawl's hosted Parse API handles those (seefirecrawl/firecrawl-sdk). - Conversions are synchronous and spawn a short-lived process. For batch pipelines, queue the work.
Testing
composer test
Unit tests always run. Integration tests convert real documents and auto-skip when the anydoc CLI is unavailable.
License
MIT