Download the PHP package kovami/htmldocx without Composer

On this page you can find all versions of the php package kovami/htmldocx. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package htmldocx

kovami/htmldocx

CI Latest version PHP version

English · Русский

Convert HTML into Word documents, and Word documents back into HTML — with one library, no runtime dependencies, and no Word, LibreOffice or headless browser anywhere in sight.

The HTML it writes is self-contained — every paragraph carries the font, size, colour, spacing and line height the document gives it — so a document looks like itself wherever it is shown. Pick the flavour your editor speaks when you have one:

Both directions meet in the middle, in one document model:

That shared model is why a document can go to Word and come back looking like itself — see Round trips.

Table of contents

Requirements

Installation

Usage

HTML to DOCX

Paper size has no HTML equivalent, so it comes from configuration — either once through Options, or per call:

DOCX to HTML

The result is a fragment by default (no <html>, no <body>), ready to drop into a page or an editor. Ask for a whole document when you need one:

A source (fromHtml, fromHtmlFile, fromDocx, fromDocxFile, fromDocxStream, fromDocument) returns a Conversion, which reads the document once and can be asked for anything: toHtml(), saveHtml(), toDocx(), saveDocx(), streamDocx() and document().

Working with the model directly

Every conversion is a read and a write, and you can stop in between — to inspect a document, to change it, or to build one yourself:

The model is plain PHP objects: Document holds a list of Paragraph and Table blocks, paragraphs hold TextRun, ImageRun, Hyperlink, Formula, NoteReference, BreakRun, TabRun and Bookmark inlines, and every one of them carries fully resolved formatting — no style lookups left to do.

Instances are immutable

A converter is safe to build once and reuse for any number of documents. The with* methods return a new instance:

Profiles

Editors disagree about markup: one wants a <figure> around a picture, another a <div>; one keeps MathML, another its own span. A profile decides which flavour of HTML is written, and teaches the reader that editor's idioms and the typography it shows text in.

Whatever profile writes the HTML, the reader understands all of them: HTML from any of these editors (and from this library's 1.x output) is read correctly by every profile.

plain CKEditor TinyMCE TipTap SunEditor
Text, lists, tables, pictures, links ✓ ✓ ✓ ✓ ✓
Footnotes and endnotes ✓ <section class="footnotes"> ✓ ✓ partly¹ ✓ se-footnotes
Formulas ✓ MathML ✓ \(…\) ✓ \(…\) ✓ inline-math ✓ KaTeX span
Headers and footers — cut, with a warning — — — ✓ se-header / se-footer
Comments — cut, with a warning — — — ✓ se-comment
Page number fields — become plain text — — — ✓ se-field

¹ The notes are written, but TipTap's schema keeps only their text: the section and the links back do not survive a round trip through it.

Base typography. Each editor shows text it has no formatting for in its own content stylesheet, and a profile assumes exactly that, so a document made in the editor reads in Word the way it looked: CKEditor's Helvetica at the browser's medium size with 1.5 line spacing, TinyMCE's system font stack with 1.4, SunEditor 3's Helvetica Neue 16px in #333 with 1.5 line spacing. Plain HTML assumes Calibri 11pt. TinyMCE's stack starts with "whatever this system calls its own font", which a DOCX cannot ask for: Word gets Segoe UI, which is what Windows shows, while macOS shows San Francisco with other metrics, so text runs longer or shorter there. If your application styles its editor differently — most do — or its users are on a Mac, say so:

A generic family — monospace, sans-serif, serif — reaches Word as Courier New, Arial or Times New Roman, and its lines are spaced as Chromium on macOS draws it, in Courier, Helvetica or Times.

Editor configuration. Editors drop what their schema does not know: out of the box CKEditor, TipTap and SunEditor keep a quarter to a half of the formatting this library writes (TinyMCE nearly all of it). With the plugins and allow-lists below they keep 97.9–99.7%, and what they hand back prints at 96.1–97.3% of the ink Word puts on the page (see the bench below). The exact configurations the bench uses live in bench/fidelity/editors.

Editor What it needs
CKEditor 5 The GeneralHtmlSupport plugin, allowing every element with its styles, classes and attributes: htmlSupport: { allow: [{ name: /.*/, styles: true, classes: true, attributes: true }] }, next to the table, list, image, link, block-quote and code-block plugins
TinyMCE The lists, advlist, table, link and image plugins; it keeps the rest of the markup as it is
TipTap StarterKit with TableKit, TextStyleKit, TextAlign, Image (inline: true, allowBase64: true), Subscript, Superscript, Highlight, Mathematics — and an extension that keeps style and id on blocks, pictures and scripts, and letter spacing on textStyle (addGlobalAttributes), which TipTap drops unless a node or mark declares them
SunEditor 3 All of its plugins, KaTeX as externalLibs: { katex: { src: katex } }, elementWhitelist: 'section\|colgroup\|col', attributeWhitelist: { '*': 'style\|id\|role\|start\|value\|data-[^\\s]+' }, and strictMode with attrFilter: false and styleFilter: false (its other filters stay on)

How close it looks

The repository carries a bench that answers the question with numbers instead of adjectives (bench/fidelity, macOS with Microsoft Word):

Plain HTML and SunEditor are the profiles tuned first; the other editors follow.

Share of the ink in place within 1.33 pt, higher is better.

DOCX → HTML: Word prints the document; the library's HTML — passed through the editor with the configuration below, and shown with its content stylesheet — is printed by Chromium on the same page, body text only (headers, footers, notes and comments differ by design).

Document Plain HTML SunEditor CKEditor TinyMCE TipTap
Text and character formatting 94.3% 92.8% 92.2% 94.2% 92.8%
Fonts and typography 98.1% 98.1% 98.2% 98.1% 98.2%
Lists 96.2% 96.2% 96.2% 96.2% 96.3%
Tables 92.4% 92.4% 92.4% 92.4% 92.4%
Pictures 100.0% 100.0% 100.0% 100.0% 100.0%
A six-page report 97.7% 97.7% 97.7% 97.7% 97.7%
Footnotes and endnotes 100.0% 100.0% 100.0% 100.0% 100.0%
Headers, footers, comments 100.0% 100.0% 100.0% 100.0% 100.0%
Mean 97.3% 97.2% 97.1% 97.3% 97.2%

HTML → DOCX: the editor's own HTML shown in Chromium with its content stylesheet, against Word's print of the DOCX the library writes from it.

Document Plain HTML SunEditor CKEditor TinyMCE TipTap
Text and character formatting 96.8% 96.7% 97.0% 19.5% 96.8%
Lists 93.5% 100.0% 96.9% 31.3% 94.9%
Tables 99.4% 98.5% 98.7% 59.1% 98.2%
Pictures 99.6% 97.3% 98.2% 69.1% 99.5%
Mean 97.3% 98.1% 97.7% 44.7% 97.4%

See it rather than read about it: the examples are a report Word wrote, the HTML this library makes of it, the DOCX it makes from editor HTML, and page images of each next to Word's own print.

Word, plain HTML and the SunEditor profile, side by side
Editor HTML in a browser, and the DOCX made from it in Word

Options

One Options object configures both directions. The first block describes the environment a document lives in — the font, size and colour text falls back to, and the stylesheet HTML is interpreted against.

Option Default Applies to What it does
fontFamily the profile's both Base font of text nothing else formats (Profiles)
fontSizePt the profile's both Base size, in points
textColor the profile's both Base colour, RRGGBB
language null HTML → DOCX Proofing language written into the document, e.g. ru-RU
pageLayout A4 portrait HTML → DOCX Paper size, orientation and margins
defaultStylesheet the profile's both Replaces the built-in defaults: the editor's content CSS for its profile, a browser's for plain HTML
extraStylesheet '' both CSS applied above the defaults and below the document's own <style>
title, author null HTML → DOCX Document properties (the title falls back to <title>)
createdAt now HTML → DOCX Fixed timestamp, for byte-reproducible output
cssUnit px DOCX → HTML Unit for lengths and font sizes: px or pt
includeHiddenText false DOCX → HTML Keep text Word marks as hidden
includeHeadersFooters true DOCX → HTML Keep page headers and footers
includeComments true DOCX → HTML Keep reviewers' comments and the text they are anchored to
idPrefix '' DOCX → HTML Prepended to generated ids (bookmarks, notes) so several documents can share one page
fullHtmlDocument false DOCX → HTML Wrap the fragment in <html><head>…<body>
maxDocxEntryBytes 128 MB DOCX → HTML Decompressed size limit of one package part
maxDocxTotalBytes 512 MB DOCX → HTML Decompressed size limit of the whole package

Options is immutable; with() copies it with changes:

Every block of the HTML this library writes carries its own formatting, whatever profile writes it, so the document looks like itself in an editor, in an email, or on a page with a stylesheet of its own.

Images

Into a document. <img src> values are resolved by an ImageSourceResolver. Out of the box, data: URIs work and nothing else does — a converter does not fetch from the network or read the disk unless you say so:

Implement ImageSourceResolver yourself to load from object storage, a CDN or a database. PNG, JPEG, GIF, BMP and TIFF are embedded as they are; WebP is converted to PNG when ext-gd is available; anything else is left out (with a warning). Images are scaled to the CSS width/height you give them, keep their aspect ratio when only one is set, and are capped at the text column width.

Out of a document. Pictures found in a .docx are placed by an ImageHandler. The default embeds them as data URIs; hand them to your own storage instead:

$image->bytes come from the document, so treat them as untrusted. Only pictures recognised by their signature (PNG, JPEG, GIF, BMP, TIFF, WebP converted to PNG) reach the handler; SVG, which can carry scripts, and Windows metafiles are skipped with a warning. Store them under the extension the library gives, serve them with its contentType and X-Content-Type-Options: nosniff, and preferably from a separate domain, so that a file served under the wrong type is never interpreted as a page on your own site.

Warnings

Anything a document carries but the conversion cannot represent is reported rather than silently dropped:

You will hear about embedded alternative-format content, pictures whose data is missing or unreadable, and package parts that could not be parsed.

Wiring it into an application

The library knows nothing about frameworks: it is a handful of plain classes with no dependencies and no global state, so wiring is a few lines wherever your application builds its services. A converter is immutable and safe to share, so build one and reuse it.

PageLayout::fromArray() takes the shape configuration files tend to have, so paper can live in your own config:

Symfony builds it through a factory, which gives you the same control as above:

What it converts

HTML → DOCX

CSS is actually cascaded. Inline style attributes, <style> blocks in the document, the configured stylesheets and presentational attributes (align, width, bgcolor, border…) are resolved the way a browser resolves them: full selector support through the native DOM (combinators, attribute selectors, structural pseudo-classes), specificity, !important, inheritance and shorthand expansion (margin, padding, border, background, font, text-decoration, list-style, logical properties). Lengths in px, pt, pc, in, cm, mm, q, em, rem, ex, ch and % are understood, and colours as hex, rgb(), rgba(), hsl() and named colours.

Content How it arrives in Word
Paragraphs, div, section, article, blockquote, pre, address, … Paragraphs, with margins as spacing, padding and borders as paragraph borders, background as shading
h1–h6 Real Heading 1–6 styles, so the navigation pane and a table of contents work
b, strong, i, em, u, s, del, sup, sub, mark, small, code, q, … Character formatting: weight, style, underline (including its style), strike-through, position, colour, highlight, font, size, letter spacing, caps and small caps, shadow and kerning
ul, ol, nested lists Real Word numbering: bullet shapes per depth, start, value, reversed, and list-style-type — including counter styles Word has no format for, which are written out as literal markers
table with thead/tbody/tfoot, caption, colgroup Tables with a column grid, repeating header rows, colspan/rowspan, per-cell borders, shading, padding, vertical alignment and widths (fixed or percentage)
img Embedded pictures, scaled to their CSS size
a href Hyperlinks; href="#id" becomes a bookmark link, and only ids something links to become bookmarks
br, hr, tabs Line breaks, a bordered rule paragraph, tab characters
page-break-before / page-break-after Page breaks
MathML, \(…\) and \[…\], TipTap's math nodes, SunEditor's KaTeX span Office Math — the formula is translated into an equation Word lays out and can edit
<section class="footnotes"> / endnotes and the superscript marks linking into them (SunEditor's se-footnotes too) Real footnotes and endnotes, so what this library wrote as HTML goes back as notes
<div class="se-header"> / se-footer, with data-type="first" or "even" Page headers and footers, including a different first page and different even pages
<span class="se-field" data-field="PAGE"> / NUMPAGES Page number and page count fields Word keeps up to date
<span class="se-comment" data-comment="1 2"> and <ol class="se-comments"> Comments on the marked text — ranges may cross paragraphs and overlap — with author, initials, date, replies and the resolved state
float: left / right on a picture A picture anchored to that side of the column, with the text wrapping around it
iframe, video, audio, embed, object A link to the source, since Word cannot play them
input Checkboxes and radios as ☑ / ☐, other controls as their value
dir="rtl", direction Right-to-left paragraphs
<title> Document title

Whitespace follows the CSS rules — collapsing, pre, pre-wrap, pre-line, nowrap — and text-transform, first-line indentation, line-height (as a multiple or a fixed height) and text-align (including justify) all survive. Malformed markup is handled the way browsers handle it, because it is parsed by the same kind of parser.

DOCX → HTML

Formatting is resolved the way Word resolves it — document defaults, style inheritance chains, numbering levels, table styles and direct formatting, each layer in the right order — and then written as HTML that shows the same thing without needing a stylesheet. The rows below describe plain HTML; a profile writes the same content in its editor's idiom (Profiles).

Content How it arrives in HTML
Paragraphs and their styles <p>, or <h1>–<h6> when the paragraph has an outline level, with spacing, indentation, alignment, borders, shading and line height as inline styles
Character formatting <strong>, <em>, <u>, <del>, <sup>, <sub> inside a <span> carrying font, size, colour, highlight and shadow; kerning only where Word kerns
Theme fonts and colours Resolved through theme1.xml, including tints and shades
Numbering Real <ul>/<ol> nesting, start and value, CSS counter styles where one fits, and the exact marker text where none does (1.2., A), α.)
Tables <table> with a <colgroup>, <thead>, rowspan/colspan, and the formatting the table style implies — header rows, banded rows, first/last column, corner cells
Pictures <img> with its size, alone in its paragraph or in the line; a floating one keeps its float and the text around it. The SunEditor profile wraps it in the image component its toolbar can select and resize
Footnotes and endnotes Superscript links to <section class="footnotes"> / endnotes at the end (DPUB-ARIA roles), with links back to the reference
Headers and footers Kept only by the SunEditor profile, as <div class="se-header"> before the content and <div class="se-footer"> after it, the first-page and even-page variants carrying data-type; they are the ones the last section shows. Other profiles cut them and say so through the warning handler
Page numbers <span class="se-field" data-field="PAGE"> (SunEditor profile) or the number Word last showed, as text
Comments Kept only by the SunEditor profile: the text each one is about wrapped in <span class="se-comment" data-comment="…">, and an <ol class="se-comments"> after the notes — one li per comment with data-author, data-initials, data-date, data-parent for a reply and data-resolved
Hyperlinks and bookmarks <a href> and <a id>, including cross-reference and HYPERLINK fields
Fields Their current result (dates, references, form checkboxes); page numbers stay fields
Tracked changes Shown accepted: insertions kept, deletions and moved-away text dropped
Office Math MathML with the LaTeX kept as an annotation, or the shape the profile's editor reads
Text boxes and shapes Their text, as paragraphs after the one they hang on
Symbols and dingbats Mapped to real Unicode characters
Line and page breaks, tabs <br>, page-break-before, preserved whitespace; in an indented paragraph the text after a tab lands on Word's stops, which count from the margin
Section geometry Page size and margins, as the width the content is laid out against

Content controls, smart tags and alternative-content wrappers are transparent — what is inside them is read normally.

What it does not do

Being explicit is more useful than a long feature list, so:

A few differences are the two engines disagreeing, not the conversion losing anything, and they are what keeps the bench above from reading 100%:

Round trips

The HTML writer only writes what differs from the stylesheet the HTML will be read against, and the HTML reader resolves that same stylesheet — so a document survives the loop instead of accumulating markup. Concretely:

Vertical spacing works the way Word works it: between two paragraphs Word leaves the larger of the space after the first and the space before the second, exactly as CSS margins collapse, so the gaps you see in the browser are the gaps Word prints.

Safety

Documents arrive from users, so the reader treats them as hostile input:

Errors that stop a conversion are thrown as Kovami\HtmlDocx\Exceptions\HtmlDocxException.

Upgrading from 1.x

The 1.x methods are gone: a converter is now chosen with plain() or for(), a source is read once, and the result is asked for from the Conversion it returns.

1.x 2.0
new HtmlDocx($options) HtmlDocx::plain($options), or HtmlDocx::for(Editor::SunEditor, $options) for SunEditor's markup
$c->htmlToDocx($html) $c->fromHtml($html)->toDocx()
$c->htmlToDocxFile($html, $path) $c->fromHtml($html)->saveDocx($path)
$c->htmlToDocxStream($html, $stream) $c->fromHtml($html)->streamDocx($stream)
$c->docxToHtml($bytes) $c->fromDocx($bytes)->toHtml()
$c->docxFileToHtml($path) $c->fromDocxFile($path)->toHtml()
$c->docxStreamToHtml($stream) $c->fromDocxStream($stream)->toHtml()
$c->readDocx($bytes) $c->fromDocx($bytes)->document()
$c->readHtml($html) $c->fromHtml($html)->document()
$c->writeDocx($document) $c->fromDocument($document)->toDocx()
$c->writeDocxToStream($document, $stream) $c->fromDocument($document)->streamDocx($stream)
$c->writeHtml($document) $c->fromDocument($document)->toHtml()

Two more things changed:

The markup 1.x wrote (SunEditor 2's) is still read by every profile's reader, so stored HTML keeps working. Since 2.2 HtmlDocx::for(Editor::SunEditor) writes for SunEditor 3; an application still on SunEditor 2 should pass SunEditor 2's content stylesheet as extraStylesheet, or stay on 2.1.

Contributing

See CONTRIBUTING.md.

License

MIT — see THIRD-PARTY-NOTICES.md.


All versions of htmldocx with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
ext-dom Version *
ext-mbstring Version *
ext-xmlwriter Version *
ext-zlib Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package kovami/htmldocx contains the following files

Loading the files please wait ...