Handling of RTF Document in Javascript - React - Angular
Tags: rtf, javascript, react, angular
Published: 2022-10-14 08:59:27

**Handling of RTF document in React-Javascript-angular**

Please refer this Package :  [RTF](https://www.npmjs.com/package/rtf.js)

Also attaching sample HTML file which will help you in Using this RTF library Further.

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">

    <script src="../.common/dep/jquery.min.js"></script>

    <script src="../../dist/WMFJS.bundle.js"></script>
    <script src="../../dist/EMFJS.bundle.js"></script>
    <script src="../../dist/RTFJS.bundle.js"></script>

    <script>
function closeDoc(reset) {
    $("#havemeta").hide();
    $("#meta").empty();
    $("#content").empty();
    $("#dropzone").show();
    $("#opened_doc").hide();
    $("#closed_doc").show();
    $("#tools").hide();
    if (reset)
        $("#samplecombo").val("");
}
function beginLoading() {
    closeDoc(false);
    $("#dropzone").hide();
    $("#content").text("Loading...");
}
function setPictBorder(elem, show) {
    return elem.css("border", show ? "1px dotted red" : "none");
}
function setUnsafeLink(elem, warn) {
    return elem.css("border", warn ? "1px dashed red" : "none");
}
function displayRtfFile(blob) {
    try {
        var legacyPictures = $("#legacypicts").prop("checked");
        var showPicBorder = $("#showpicborder").prop("checked");
        var warnHttpLinks = $("#warnhttplink").prop("checked");
        var settings = {
            onPicture: function(isLegacy, create) {
                // isLegacy is null if it's the only available picture (e.g. legacy rtf)
                if (isLegacy === null || isLegacy === legacyPictures) {
                    var elem = $(create()).attr("class", "rtfpict"); // WHY does addClass not work on <svg>?!
                    return setPictBorder(elem, showPicBorder)[0];
                }
            },
            onHyperlink: function(create, hyperlink) {
                var url = hyperlink.url();
                var lnk = create();
                if (url.substr(0, 7) == "http://") {
                    // Wrap http:// links into a <span>
                    var span = setUnsafeLink($("<span>").addClass("unsafelink").append(lnk), warnHttpLinks);
                    span.click(function(evt) {
                        if ($("#warnhttplink").prop("checked")) {
                            evt.preventDefault();
                            alert("Unsafe link: " + url);
                            return false;
                        }
                    });
                    return {
                        content: lnk,
                        element: span[0]
                    };
                } else {
                    return {
                        content: lnk,
                        element: lnk
                    };
                }
            },
        };
        var doc = new RTFJS.Document(blob, settings);
        var haveMeta = false;
        var meta = doc.metadata();
        for (var prop in meta) {
            $("#meta").append($("<div>").append($("<span>").text(prop + ": ")).append($("<span>").text(meta[prop].toString())));
            haveMeta = true;
        }
        if (haveMeta)
            $("#havemeta").show();
        doc.render().then(html => {
            $("#content").empty().append(html);
            $("#closed_doc").hide();
            $("#opened_doc").show();
            $("#tools").show();
            console.log("All done!");
        }).catch(e => {
            if (e instanceof RTFJS.Error) {
                $("#content").text("Error: " + e.message);
                throw e;
            }
            else {
                throw e;
            }
        });
    } catch(e) {
        if (e instanceof RTFJS.Error) {
            $("#content").text("Error: " + e.message);
            throw e;
        }
        else {
            throw e;
        }
    }
}
function stringToBinaryArray(string) {
    var buffer = new ArrayBuffer(string.length);
    var bufferView = new Uint8Array(buffer);
    for (var i=0; i<string.length; i++) {
        bufferView[i] = string.charCodeAt(i);
    }
    return buffer;
}
function loadRtfFile(file) {
    beginLoading();
    $.ajax({
        url: file,
        dataType: "text",
        processData: false,
        success: function(result) {
            displayRtfFile(stringToBinaryArray(result));
        },
        error: function(jqXHR, textStatus, errorThrown) {
            $("#content").text("Error: " + errorThrown);
        }
    });
}
$(document).ready(function() {
    $("#closebutton").click(function() {
        closeDoc(true);
    });
    $("#samplecombo").change(function() {
        var file = $(this).val();
        if (file.length == 0) {
            closeDoc(true);
        } else {
            loadRtfFile('../.common/data/rtf/' + $(this).val());
        }
    });
    $("#showpicborder").change(function() {
        var show = $(this).prop("checked");
        $(".rtfpict").each(function() {
            setPictBorder($(this), show);
        });
    });
    $("#warnhttplink").change(function() {
        var warn = $(this).prop("checked");
        $(".unsafelink").each(function() {
            setUnsafeLink($(this), warn);
        });
    });
    $("#dropzone")
        .on("drop", function(evt) {
            evt.stopPropagation()
            evt.preventDefault();

            var files = evt.originalEvent.dataTransfer.files;
            if (files.length > 1) {
                alert("Please only drop one file!");
            } else {
                var reader = new FileReader();
                reader.onload = function(evt) {
                    beginLoading();
                    setTimeout(function() {
                        displayRtfFile(evt.target.result);
                    }, 100);
                };
                reader.readAsArrayBuffer(files[0]);
            }
        })
        .on("dragover", function(evt) {
            evt.stopPropagation()
            evt.preventDefault();
        });

    closeDoc(true);
});
    </script>
</head>
<body>
<div style="margin: 4pt;">
    <span>
        <form>
            <span id="opened_doc" style="display: none;">
                <input id="closebutton" type="button" value="Close"/>
            </span>
            <span id="closed_doc">
                <select id="samplecombo">
                    <option selected="selected" value="">Drag&amp;Drop a RTF document</option>
                    <option>simple1.rtf</option>
                    <option>simple2.rtf</option>
                    <option>simple3.rtf</option>
                    <option>simple4.rtf</option>
                    <option>simple5.rtf</option>
                    <option>simplepict.rtf</option>
                    <option>simplepng.rtf</option>
                    <option>simplepngbin.rtf</option>
                    <option>hyperlink.rtf</option>
                </select>
                <label><input id="legacypicts" type="checkbox" checked/>Load legacy pictures</label>
            </span>
        </form>
    </span>
    <span id="tools" style="display: none;">
        <label><input id="showpicborder" type="checkbox"/>Picture border</label>
        <label><input id="warnhttplink" type="checkbox"/>Protect from unsafe links</label>
    </span>
</div>
<div id="dropzone" style="display: inline-block; border-radius: 6pt; border: 2pt solid #dddddd; padding: 30pt;">
    Drop an RTF document here
</div>
<div style="background-color:#f0ffff;display:none;" id="havemeta">
    <div>Metadata:</div>
    <div id="meta"></div>
</div>
<div id="content"></div>
</body>
</html>

```
**Working sample created with Javscript**
```js
// add this dependency in package.json
import * as rtfjs from "rtf.js";

const rtfData = (data, elementLabel, index = 0) => {
  if (data) {
    if (data?.toLowerCase().includes("rtf")) {
      const { RTFJS } = rtfjs;
      RTFJS.loggingEnabled(false);
      try {
        const doc = new RTFJS.Document(stringToArrayBufferChange(data), {});
        const meta = doc.metadata();
        doc
          .render()
          .then(function (htmlElements) {
            let lastElementIndex = htmlElements.length - 1;
            htmlElements.forEach((eachHtml, idx) => {
              if (eachHtml.innerText.trim()) {
                lastElementIndex = idx;
              }
            });
            htmlElements.forEach((eachHtml, idx) => {
              if (idx <= lastElementIndex) {
                document
                  .getElementById(`${elementLabel}-${index}`)
                  ?.append(eachHtml);
              }
            });
          })
          .catch((error) => console.error(error));
      } catch {
        const element = document.createElement("span");
        element.append("Error processing event notes");
        element.style.color = "red";
        document.getElementById(`${elementLabel}-${index}`)?.append(element);
      }
    } else {
      const element = document.createElement("span");
      element.append(data);
      document.getElementById(`${elementLabel}-${index}`)?.append(element);
    }
  }
};

const stringToArrayBufferChange = (str) => {
  const buffer = new ArrayBuffer(str.length);
  const bufferView = new Uint8Array(buffer);
  for (let i = 0; i < str.length; i++) {
    bufferView[i] = str.charCodeAt(i);
  }
  return buffer;
};

```