I faced the same problem recently: I wanted to export some JSX pages in my React App to a Word document, and spent a long time looking up various solutions online for it.
Demo: button on the lower right
Published as an NPM package here
In the end, I did it by tweaking a jQuery plugin called jQuery-Word-Export. This has been tested on Microsoft Word for Mac.
As explained in the ReadMe, the basic idea behind the plugin is this:
“This plugin takes advantage of the fact that MS Word can interpret
HTML as a document. Specifically, this plugin leverages the MHTML
archive format in order to embed images directly into the file, so
they can be viewed offline.”
For a more in-depth discussion, see here. In short, the user gets a "Single File Web Page", which they can open and edit with Microsoft Word (as though it is an ordinary .doc or .docx file).
In terms of implementation, I first collected all the pages I wanted to convert to Word with React.forwardRef,
export const ComponentToPrint =
React.forwardRef((props, ref) => {
return (
<div ref={ref}>
<NoticeOfMotion />
<br className="pagebreak"></br>
<AffidavitOfApplicant />
<br className="pagebreak"></br>
<AffidavitOfIdentity />
<br className="pagebreak"></br>
<CoverLetters />
</div>
);
});
I then tweaked the jQuery plugin and replaced jQuery specific syntax with ordinary Javascript,
import { TailwindStyles } from "../helper/TailwindStyles.html";
import { saveAs } from "file-saver";
export function exportHTML(sourceRef) {
const sourceHTML = sourceRef.current.innerHTML;
var statiC = {
mhtml: {
top:
/* eslint-disable */
"Mime-Version: 1.0\nContent-Base: " +
location.href +
'\nContent-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset="utf-8"\nContent-Location: ' +
location.href +
"\n\n<!DOCTYPE html>\n<html>\n_html_</html>",
head: '<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n<style>\n_styles_\n</style>\n</head>\n',
body: "<body>_body_</body>",
},
};
// Clone selected element before manipulating it
var markup = sourceHTML
// Prepare bottom of mhtml file with image data
var mhtmlBottom = "\n";
mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";
var styles = TailwindStyles;
// Aggregate parts of the file together
var fileContent =
statiC.mhtml.top.replace(
"_html_",
statiC.mhtml.head.replace("_styles_", styles) +
statiC.mhtml.body.replace("_body_", markup),
) + mhtmlBottom;
// Create a Blob with the file contents
var blob = new Blob([fileContent], {
type: "application/msword;charset=utf-8",
});
saveAs(blob, `Barrister Admission Bundle(beta).doc`);
}
Finally I wired them up in my "Enter Information" page like so,
<div className="hidden">
<ComponentToPrint ref={sourceRef} id="source-html" />
</div>
<div>
<button
onClick={() => exportHTML(sourceRef)}>
Download as Word.doc file
</button>
</div>
The result is that if you click the button on the lower right here, you should get a file with a .doc prefix, which Microsoft Word for Mac should open by default with Word. You can also edit it and save it as though it is an ordinary Word document.
For completeness, the solutions proposed by the others above didn't work for me.
redocx is solving the problem I want to solve. But when I run the demo on the machine, I get this warning,
"Word found unreadable content in HelloWorld.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes."
I also cannot edit and save the Word document without altering the format.
As for docx, that tool seems to be solving a different problem. You need to write the React components following some specific rules in order for the formatting to work on Word.
But I take it the nub of this question is how to convert export HTML+CSS (i.e. not specifically written for docx npm package or other tools) as a (reasonably styled) Word document.
The tutorial in https://www.codexworld.com/export-html-to-word-doc-docx-using-javascript/ is trying to solve the right problem. But for Microsoft Word for Mac it did not succeed in producing a document that can be edited with Word and then successfully saved. An error message appears and the user needs to save in an alternative format.
A further alternative tool that I initially investigated is pandoc-server. An impressive demo is here.
But according to its docs, pandoc-server needs to work in a server, where I need to use the executable of pandoc-server (which should be a binary file) as a CGI (common gateway interface) file.
This is quite involved, especially if it is originally not intended to set up a server for the task.