how can I export react to word document
Asked Answered
R

4

6

I have a React app and I want to export some html content to word document and download it. for example:

<div> Hello World!!!</div>
<input type="button" onClick={exportToWord()}/>

I search for a function that will handle a word document with the text Hello world!!!.

Ruralize answered 12/12, 2019 at 11:33 Comment(0)
R
4

you can use redocx library for word documents with React you can install redocx by NPM

npm i redocx

this simple example will render Hello World in word doc

import React from 'react'
import { render, Document, Text } from 'redocx'

class App extends React.Component {
  render() {
    return (
      <Document>
        <Text>Hello World</Text>
      </Document>
    )
  }
}

render(<App />, `${__dirname}/example.docx`)

for Demo you can clone this repo and run locally

git clone https://github.com/nitin42/redocx.git
cd redocx
npm install
npm run example

you can find all documentation here redocx docs

Rone answered 12/12, 2019 at 11:44 Comment(0)
P
2

You can use docx npm package

Here is a button onClick callback example:

async function exportToWord() {
    const doc = new Document({
        sections: [{
            properties: {},
            children: [
                new Paragraph({
                    children: [
                        new TextRun("Hello World")
                    ],
                 }),
            ],
         }]
    });
    const buffer = await Packer.toBuffer(doc);
    const blob = new Blob([buffer], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"});
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = 'my.docx';
    link.click();
}
Pedestal answered 26/5, 2021 at 14:55 Comment(1)
This doesn't convert a react component to word docsMesial
A
0

Check this out https://www.codexworld.com/export-html-to-word-doc-docx-using-javascript/

 function Export2Word(filename = "") {
    var preHtml =
      "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>";
    var postHtml = "</body></html>";

    var html = preHtml + dom + postHtml;

    var blob = new Blob(["\ufeff", html], {
      type: "application/msword",
    });

    // Specify link url
    var url =
      "data:application/vnd.ms-word;charset=utf-8," + encodeURIComponent(html);

    // Specify file name
    filename = filename ? filename + ".doc" : "document.doc";

    // Create download link element
    var downloadLink = document.createElement("a");

    document.body.appendChild(downloadLink);

    // Create a link to the file
    downloadLink.href = url;

    // Setting the file name
    downloadLink.download = filename;

    //triggering the function
    downloadLink.click();

    document.body.removeChild(downloadLink);
}
Amaryl answered 2/5, 2023 at 17:26 Comment(0)
S
0

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.

Sami answered 23/4, 2024 at 15:27 Comment(2)
This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can follow this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From ReviewYeargain
Thank you for the feedback. I have rewritten to directly answer the question.Sami

© 2022 - 2025 — McMap. All rights reserved.