Download the PHP package dskripchenko/php-docx without Composer
On this page you can find all versions of the php package dskripchenko/php-docx. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download dskripchenko/php-docx
More information about dskripchenko/php-docx
Files in dskripchenko/php-docx
Package php-docx
Short Description The HTML layer for PHPWord pipelines and a standalone DOCX-HTML round-trip library: read arbitrary Word/Google Docs/LibreOffice/PHPWord documents to a typed AST and clean HTML, convert HTML to DOCX, detect MERGEFIELD/content-control/{{placeholder}} template variables. Pure PHP, zero dependencies.
License MIT
Informations about the package php-docx
dskripchenko/php-docx
π English Β· δΈζ
The HTML layer for your PHPWord pipeline β and a standalone
DOCX β HTML round-trip library. Pure-PHP: read arbitrary Word /
Google Docs / LibreOffice / PHPWord documents into a typed AST, turn
them into clean HTML, convert HTML into DOCX, detect template variables
(MERGEFIELD, content controls, {{placeholders}}). Works next to
PHPWord, not instead of it. No
external dependencies beyond standard PHP extensions.
Read this in other languages: English Β· Π ΡΡΡΠΊΠΈΠΉ Β· δΈζ Β· Deutsch
Table of contents
- Features
- php-docx and PHPWord
- Requirements
- Installation
- Quick start
- HTML β DOCX
- Programmatic builder
- DOCX β HTML / AST
- HTML β DOCX
- Programmatic builder API
- DOCX β HTML (Reader)
- Headers, footers & watermarks
- Variable detection
- Length helpers
- AST overview
- Round-trip
- Architecture
- Development
- License
Features
- HTML β DOCX writer β full set of typical layout elements (paragraphs/headings/tables/lists/images/links/fields), inline-style resolution, custom heading registry.
- DOCX β HTML reader β parses arbitrary Word/Pages/LibreOffice documents into a typed AST, then serialises back to HTML with inline styles. Style cascade (docDefaults β named β direct), theme colors, numbering reconstruction, vMerge/gridSpan collapse, watermark detection (VML + DrawingML).
- Fluent programmatic builder β
DocumentBuilderwith closure scopes for nested structures (tables, lists, headers). - Variable detection β MERGEFIELD, SDT content controls, configurable
text patterns (
{{x}},${x},%x%). - Multi-header/footer β default / first-page / even-pages variants
with automatic
<w:titlePg/>and<w:evenAndOddHeaders/>plumbing. - Round-trip safe β read DOCX β AST β write DOCX produces a valid document; bytes-level differences are limited to whitespace/ordering.
- PHP 8.2+ β
readonlyvalue-objects, named arguments, constructor promotion, enums. - Zero composer dependencies.
Out of scope
Tracked changes, comments, embedded charts, OLE objects, footnotes/endnotes, SmartArt, math equations (OMML), form fields, custom XML parts.
Examples
Runnable scripts with committed output live in
examples/: HTML β DOCX with headers and
watermarks, the fluent builder, DOCX β HTML import, template-variable
detection and substitution, round-trip stability, CSS inlining, and the
PHPWord bridge.
php-docx and PHPWord
PHPWord is the established library for building Word documents in PHP. php-docx does not replace it β it adds the two things PHPWord is weakest at: reading arbitrary DOCX (with a full style cascade) and HTML in both directions. Use both, each for what it does best.
What php-docx adds next to PHPWord:
- reading real-world DOCX (Word, Google Docs, LibreOffice, PHPWord output) into a typed AST β verified continuously on an external corpus, see the reader-fidelity dashboard;
- DOCX β clean HTML with inline styles (style cascade, theme colours, numbering, merged cells);
- HTML β DOCX;
- template-variable detection (MERGEFIELD, SDT content controls,
{{x}}/${x}/%x%patterns).
What php-docx deliberately does not do (PHPWord or other tools do): ODF/RTF/PDF output, tracked changes, comments, footnotes/endnotes, charts, OMML math, form fields.
Zero-integration recipe β works today, no bridge required. PHPWord writes the file, php-docx reads the bytes:
A typed object-level bridge (PhpWordBridge::toHtml($phpWord), HTML
import into PHPWord objects, reading straight into PHPWord models) ships
separately as dskripchenko/php-docx-phpword.
Requirements
- PHP 8.2+
ext-zip,ext-dom,ext-mbstring
Installation
Quick start
1. HTML β DOCX
2. Programmatic builder
3. DOCX β HTML / AST
HTML β DOCX
Input HTML must use inline styles only (no <style> blocks). Use a
CSS-inliner upstream if needed.
Supported elements
| Category | HTML tags |
|---|---|
| Text blocks | <p>, <h1..h6>, <div>, <pre>, <blockquote> |
| Inline marks | <strong>/<b>, <em>/<i>, <u>, <s>/<del>, <sup>, <sub>, <mark> |
| Code/teletype | <code>, <kbd>, <samp>, <var>, <cite>, <dfn>, <q>, <small> |
| Links | <a href> external, <a href="#anchor"> internal, <a id> bookmarks |
| Images | <img src="data:image/...;base64,..."> |
| Tables | <table>, <thead>/<tbody>, <tr>, <th>/<td>, <colgroup>/<col>, <caption>, colspan, rowspan |
| Lists | <ul>, <ol type="a/A/i/I" start="N">, <li value="N">, <dl>/<dt>/<dd> |
| Custom tags | <page-number/>, <page-total/>, <current-date format="...">, <page-break> |
| Marker classes | class="page-number", class="page-total", class="page-break" β same fields, spelled so an HTML sanitizer keeps them |
| Layout | <hr>, <br>, <figure>/<figcaption> |
Inline styles
The converter understands style="β¦" properties:
- Run-level:
font-family,font-size,font-weight,font-style,text-decoration,color,background-color,letter-spacing - Paragraph-level:
text-align,margin,text-indent,line-height,border,padding,background-color - Table-level:
width,border,border-collapse - Cell-level:
width,padding,border,vertical-align,background-color
Custom tags
These become OOXML field codes (<w:fldSimple w:instr="PAGE">).
Custom heading styles
Stylesheets and classes
fromHtml() understands inline styles only. For HTML carrying
<style> blocks or class-based styling, use fromHtmlWithStyles() β
it first runs the document through an HtmlPreprocessor. The default
implementation inlines CSS via the optional
tijsverkoyen/css-to-inline-styles
package (composer require tijsverkoyen/css-to-inline-styles; php-docx
itself stays zero-dependency), and you can plug your own preprocessor:
Programmatic builder API
The Build namespace provides a fluent API for assembling DOCX
documents block by block, finalising to the same immutable AST that the
HTML pipeline produces.
DocumentBuilder
Entry point. Accumulates body, header/footer, watermark, page setup.
ParagraphBuilder
Inside ->paragraph(fn ($p) => β¦):
Paragraph-level styling:
TableBuilder
Spans and merges:
ListBuilder
RunStyleBuilder
Used inside ->styled(text, fn (RunStyleBuilder) => β¦) or standalone via
RunStyleBuilder::new()->β¦->build().
Length helpers
Convert common units to OOXML twips (1 twip = 1/20 pt). Used wherever a twip int is expected.
Most builders expose unit-aware shortcuts:
- TableBuilder:
widthPt/widthMm/widthCm/widthInches,cellMarginsMm/cellMarginsPt - TableCellBuilder:
widthPt/Mm/Cm/Inches,paddingMm/Pt/Cm/Inches - ColumnBuilder:
widthPt/Mm/Cm/Inches/Px - ParagraphBuilder:
indentMm/Cm/Pt/Inches,spacingPt/Mm - RunStyleBuilder:
fontSizePt
DOCX β HTML (Reader)
High-level: DocxReader
This runs the full pipeline: package unpack β styles resolve β body/header/footer parsing β vMerge/list reconstruction β image extraction β watermark detection β page setup.
Low-level: DocxPackageReader
If you need the raw OOXML parts:
Serializer: AST β HTML
HTML output uses inline styles only β re-loadable into the same library
via Html\Converter::fromHtml($imported->bodyHtml).
Headers, footers & watermarks
Three header/footer types are supported per section: default, first
(title page), even (even pages). Word automatically renders the right
one based on page number.
The writer automatically:
- emits
<w:titlePg/>insectPrwhen first-page header/footer is set - emits
word/settings.xmlwith<w:evenAndOddHeaders/>when even header/footer is set
Watermark
Renders as a 45Β°-rotated VML text shape on every page.
Variable detection
Scans an imported DOCX for three kinds of variables:
- MERGEFIELD β Word mail-merge native, both simple
<w:fldSimple>and complex<w:fldChar>form. - SDT content controls β
<w:sdt>with<w:tag w:val="...">. - Text patterns β configurable regexes (defaults:
{{name}},${name},%name%).
Detection runs across body + all headers + all footers. Results are
deduplicated by (source, name).
Length helpers
See Length helpers above. Conversion table:
| Unit | Twips | Pt | Notes |
|---|---|---|---|
| 1 twip | 1 | 0.05 | OOXML native |
| 1 pt | 20 | 1 | typography |
| 1 mm | ~57 | 2.83 | metric |
| 1 cm | ~567 | 28.35 | metric |
| 1 inch | 1440 | 72 | imperial |
| 1 px | 15 | 0.75 | CSS @ 96 DPI |
AST overview
All elements live under Dskripchenko\PhpDocx\Element namespace.
| Element | Type | Notes |
|---|---|---|
Document |
root | { section: Section, watermarkText: ?string } |
Section |
container | { body, header, footer, pageSetup, firstHeader, firstFooter, evenHeader, evenFooter } |
Paragraph |
BlockElement | { children: InlineElement[], style: ParagraphStyle, headingLevel: ?int } |
Run |
InlineElement | { text: string, style: RunStyle } |
Hyperlink |
InlineElement | { href: ?string, anchor: ?string, children: InlineElement[] } |
Bookmark |
InlineElement | { name: string, children: InlineElement[] } |
Image |
both | { binary, format, widthEmu, heightEmu, altText } |
Field |
InlineElement | { instruction: string, style: RunStyle } |
LineBreak, PageBreak, HorizontalRule |
both | marker elements |
Table |
BlockElement | { rows: TableRow[], style, caption, gridColumnsTwips } |
TableRow |
element | { cells: TableCell[], isHeader, heightTwips } |
TableCell |
element | { children: BlockElement[], style: CellStyle } |
ListNode |
BlockElement | { items: ListItem[], ordered, format, startAt } |
ListItem |
element | { children: InlineElement[], nestedList: ?ListNode } |
Styles live under Dskripchenko\PhpDocx\Style:
RunStyleβ font, weight, italic, color, size, highlight, β¦ParagraphStyleβ alignment, indents, spacing, bordersCellStyleβ width, padding, borders, valign, gridSpan, rowSpanTableStyleβ width, borders, alignment, cell margins, layoutPageSetup,PaperSize,Orientation,Alignment,VerticalAlign,BorderStyle,Border,BorderSet
Round-trip
The library targets semantic round-trip safety, not byte equality β content, structure and styling survive, but XML ordering and whitespace may differ.
In-scope round-trip features:
- Paragraphs/headings with all run formatting
- Tables with
vMerge/gridSpanreconstruction - Lists (bullet/decimal/letter/roman) with arbitrary nesting
- Images with EMU sizes and alt text
- Hyperlinks (external + internal anchors) and bookmarks
- Headers/footers (default/first/even) and watermarks
- Field codes (PAGE, NUMPAGES, DATE, MERGEFIELD)
- Page setup (size, orientation, margins)
Out-of-scope features are silently dropped (footnotes, comments, equations, etc.).
Architecture
The same Document AST is shared by HTML conversion, programmatic
construction and DOCX reading β every entry/exit point operates on
typed value-objects.
Conformance
Every push validates the writer's output externally, not just against our own reader:
- ECMA-376 Transitional XSD β every WordprocessingML part (document, styles, numbering, headers, footers) is validated with xmllint against the official schemas (fetched from ecma-international.org, SHA-pinned);
- LibreOffice headless converts the reference document to PDF β a real-world consumer, not a mock;
- python-docx opens it and extracts the expected content β an independent reader implementation.
Reproduce locally:
Development
License
MIT β see LICENSE.
All versions of php-docx with dependencies
ext-dom Version *
ext-mbstring Version *
ext-zip Version *