Get text from a docx file in react js - reactjs

As the title states, I am trying to get the text from a docx file I store locally in my src folder. Currently I am using Docxtemplater to get text in the following way:
import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import PizZipUtils from "pizzip/utils/index.js";
import docx from "../../assets/documents/T&C.docx";
function loadFile(url, callback) {
PizZipUtils.getBinaryContent(url, callback);
}
...
const [docText, setDocText] = useState("");
loadFile(docx, function (error, content) {
if (error) {
throw error;
}
var zip = new PizZip(content);
var doc = new Docxtemplater().loadZip(zip, {
paragraphLoop: true,
linebreaks: true,
});
setDocText(doc.getFullText());
My problem for this is that I am getting a chunk of text that is neither indented or styled (meaning it is missing new line and lists are also not in the correct format). Is there any other approach to get the text from a docx file by getting the style also (new lines lists and whatever it has there, excluding images or math formulas).
I am open to using other libraries if it makes my job easier.

Related

React react-drag-drop-files upload component doesn't accept XML files with custom file extension

I am using react-drag-drop-files package to upload files. I am having problem with file types. I want to accept *.lic files, and I can not get it to work... Here is my code:
import { FileUploader } from "react-drag-drop-files";
const fileTypes = ['lic'];
<FileUploader
label="Drop your license (*.lic) file here"
handleChange={handleChange}
name="file"
types={fileTypes}
/>
When I drag and drop my file DWX-J13M-DRCI-JQR1.lic the component would say error File type/size error, Hovered on types!.
My *.lic files are basically XML files. If I rename DWX-J13M-DRCI-JQR1.lic to DWX-J13M-DRCI-JQR1.xml and fix accepted fileTypes to const fileTypes = ['xml']; than it will accept the file...
What am I doing wrong that LIC files are not accepted?
UPDATE:
I checked how react-drag-drop-files component check for fyle type, so this is very basic, I see no reasons that my custom "LIC" file extension would not be accepted:
export const checkType = (file: File, types: Array<string>): boolean => {
const extension: string = file.name.split('.').pop() as string;
const loweredTypes = types.map((type) => type.toLowerCase());
return loweredTypes.includes(extension.toLowerCase());
};

Can't read excel file in SheetJS, react

I am very new to react and try to import excel file to browse in react.
I tried to use sheetJS but it didn't work due to below error message.
TypeError: _fs.readFileSync is not a function
import React from 'react';
import XLSX from 'xlsx';
class Readfile extends React.Components {
...
var filename = 'test.xlsx';
var book = XLSX.readFile(filename);
...
Error seems to come from readFile function.
Is there any steps I missed to code? Thanks in advance.
xlsx library has support for both browser & NodeJS. However, some specific functions only work in NodeJS.
readFile functions read files from the file system and you don't have access to the file system in the browser.
In the browser following options are available:
Browser download file (ajax)
Browser drag-and-drop
Browser file upload form element
For example, this file is available on https://example.com/test.xlsx, you can use the following snippet:
var url = "https://example.com/test.xlsx";
/* set up async GET request */
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "arraybuffer";
req.onload = function(e) {
var data = new Uint8Array(req.response);
var workbook = XLSX.read(data, {type:"array"});
/* DO SOMETHING WITH workbook HERE */
}
req.send();

Load a list of internal files in react

I'm implementing a localized react app using react-intl. I have a folder with all translations. I want to dynamically import all the translations and also get the filenames to display a dropdown with available languages on the page.
Currently I have to hardcode each language:
import {IntlProvider, FormattedMessage} from 'react-intl'
import messages_de from '../translations/de.json'
import messages_en from '../translations/en.json'
const messages = {
'de': messages_de,
'en': messages_en,
};
const i18nConfig = {
defaultLocale: 'en',
messages,
};
Is there a way to get a list of files (e.g. before compiling an app) which I can then access within react components?
I ended up with the following solution:
// search for .json files
const webpackContext = require.context('../translations', false, /\.json$/)
const filenames = webpackContext.keys() // => ['./de.json, './en.json']
const key_value_pairs = filenames.map(name => [name.match(/\/(\w+)\.json$/)[1], webpackContext(name)])
// make a dictionary from the array of arrays
const messages = Object.fromEntries(key_value_pairs)
This code imports dynamically all files into a dictionary where the key is the filename.
require.context takes a directory to search, a flag indicating whether subdirectories should be searched too, and a regular expression to match files against.
The returned function webpackContext is the most confusing part. Although it is a function, it also has properties, because everything is an object in js. webpackContext.keys() returns a list of filenames in given directory matching given regex.
Finally, webpackContext(name) imports a file.
The code above is equivalent to the following code:
import messages_de from '../translations/de.json'
import messages_en from '../translations/en.json'
const messages = {
'de': messages_de,
'en': messages_en,
};

SharePoint SPFX: Unable to get property 'Context'

I'm working on a custom SPFX commandset. It opens a dialog with an iframe to an 3rth party platform. I'm able to receive a json through a postmessage. From this json, I convert it's data to a file, with it's proper metadata. All of this works like a charm... Except...
Now I want to upload this file to a document library, and it drives me crazy.
I'm referencing:
import "#pnp/polyfill-ie11";
import { ConsoleListener, Logger, LogLevel } from "#pnp/logging";
import { sp } from "#pnp/sp";
import { Web } from "#pnp/sp/webs";
import "#pnp/sp/webs";
import "#pnp/sp/files";
import "#pnp/sp/folders";
import { Base64 } from 'js-base64';
In my dialog component, I try to upload the file with web.getFolderByServerRelativeUrl. But this method is failing, and I really don't understand why.... Looking at the pnp reference (https://pnp.github.io/pnpjs/sp/files/), It seems like the right way.
var file = Base64.atob(response.Data);
console.log("File length : " + file.length);
let web = Web("https://MyTenant.sharepoint.com/sites/Customer"); // this is successful
await web.getFolderByServerRelativeUrl("/sites/Customer/Shared%20Documents/")
.files.add(response.fileName, file, true); // this fails
The context is set on the CommandSet onInit()
#override
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, 'Initialized myCommandSet');
pnpSetup({
spfxContext: this.context
});
return Promise.resolve();
}
Hope you guys and girls can point me in the right direction...
EDIT:
Error:
HTTP400: INVALID REQUEST - The request could not be processed by the server
due to an invalid syntax
POST - https://MyDevTenant.sharepoint.com/sites/customer/
_api/web/getFolderByServerRelativeUrl
('%2Fsites%2Customer%2FShared%2520Documents%2F')
/files/add(overwrite=true,url='')
Is it the url from the documentlibrary that messes things up?
Thanks to Willman for giving me a right direction.
This did the trick:
import { sp, Web, IWeb } from "#pnp/sp/presets/all";
import "#pnp/sp/webs";
import "#pnp/sp/lists";
import "#pnp/sp/files";
import "#pnp/sp/folders";
const web = await sp.web();
const list = sp.web.getList("Documents");
const listId = await list.select("Id")();
await sp.web.lists.getById(listId.Id).rootFolder.files.add(docname, file, true);

FBXLoader can't find version number of fbx file

I'm trying to load a .fbx file, the loader.load function throws the following error:
THREE.FBXLoader: Cannot find the version number for the file given.
I don't know how to solve this problem. How can I check in the fbx file if it has a version number?
Below you can find the react component that I've written. When I test the app, I see only a black canvas.
I tried two different files, but have the same error for both files.
export default class myComponent extends Component {
componentDidMount() {
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.set(2, 18, 28);
const scene = new THREE.Scene();
const light = new THREE.HemisphereLight(0xffffff, 0x444444);
light.position.set(0, 1, 0);
scene.add(light);
const gridHelper = new THREE.GridHelper(28, 28, 0x303030, 0x303030);
scene.add(gridHelper);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
this.model.appendChild(renderer.domElement);
const loader = new FBXLoader();
let model = new THREE.Object3D();
loader.load(
'./3DModels/MHT.fbx',
function(object) {
model = object.scene;
scene.add(model);
},
undefined,
function(e) {
console.log(e);
}
);
renderer.render(scene, camera);
}
render() {
return <div ref={ref => (this.model = ref)} />;
}
}
FBXLoader throws this error: THREE.FBXLoader: Cannot find the version number for the file given.
loader.load('./3DModels/MHT.fbx', function(object) {
...
})
instead:
const path = require(./3DModels/MHT.fbx);//写在类的外面
loader.load(path, function(object) {
...
})
I have meeted the same problem just now, you can try to debug like this:
I find the reason that my project use Mockjs which make XMLHttpRequest become MockXMLHttpRequest:
// relative code in three.js:
request.addEventListener( 'load', function ( event ) {
// if you use Mockjs, this become MockXMLHttpRequest but not XMLHttpRequest
// this.response not is ArrayBuffer ,there is the bug.
var response = this.response;
var callbacks = loading[ url ];
Here just my case which maybe help you.
Are you hosting your files in your src folder or public folder?
You should be keeping the fbx files in public folder.
The loader scans the document and parses the text to find what it needs to load. Case with working in react is this will trigger before the DOM is rendered, so it basicaly can't the version because it sees no file.
I worked it out while trying to "debug" the loader code. It turned out it was me :)
Another fbx thing is you should always use the latest loader plugin. Under this link you will find both the link to the original plugin and the example how to convert it to React module.
Hope this helps.
I had exactly the same error coming up on a ThreeJS RPG game hosted on Heroku. I eventually found a simple solution which worked for me and am posting here for any other poor soul who runs into to this issue.
The issue for me was that when I was downloading the FBX file from mixamo I was downloading just the FBX.binary file. **You need to download the fbx file with the version number **. So I just downloaded the FBX animation as FBX 7.4 and it worked. See image.
Hope this helps someone save the stupid number of hours I wasted on this...
download fbx 7.4 or 6.1

Resources