Can't read excel file in SheetJS, react - reactjs

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();

Related

Get text from a docx file in react js

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.

Images not loading unless I rebuild App Next JS

I am having trouble with images lately in next js. I know next has deprecated support for static in favour of public directory. So even after refactoring, I still cant get images to load. Here is the flow:
I choose an image for a project and send an axios request to the server. The server only saves the path to mongodb like this:
staticPath = `/ProjectImages/projImg_${req.decodedTokenData.userId}_${_id}_${key}.png`;
let imagePath = path.normalize(__dirname + `/../../public${staticPath}`);
dbImages.push(staticPath);
and writes the image's base64encoded value to a file and saves it to ProjectImages directory in public dir.
Now when I create a project, the images doesnt load even though it has reference to the path and the image itself is in the correct place. Only after rebuilding the app do I see the image.
Note: this issue does not occur in development mode only in production.
please help.!
Masla he koi ni
rather than calling the images from source directly i would recommend you to create a route and serve all those images from there
const express = require("express");
const router = express.Router();
const path = require('path');
const fs = require('fs');
router.get('/media/project/:path',function (req,res,next) {
const _path = `/static/ProjectImages/${req.params.path}`;
let imagePath = path.normalize(__dirname + `/../../public${_path}`);
try{
if (fs.existsSync(imagePath)) {
res.sendFile(imagePath);
}else{
res.sendStatus(404);
}
}catch (err) {
res.sendStatus(404);
}
});

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

Using Node.js I get readFileSync is not a function

I am developing a web app with Angular 2, typescript, nodejs and Visual Studio. I want to read a file located in my wwwroot folder. so far I have created the following class:
///<reference path="../../node_modules/angular2/ts/typings/node/node.d.ts"/>
export class LoadConfigurationService {
fs: any;
constructor() {
this.fs = require('fs');
let data = this.fs.readFileSync('input.txt');
}
}
The problem is that I always get the error "readFileSync is not a function". I have tried to install the node file system module by adding the following line
"file-system": "^2.2.1"
to my package.json dependencies. I've also added
"node.TypeScript.DefinitelyTyped": "2.8.8"
to my project.json dependencies. But it keeps giving me the same error. What am I doing wrong?
Your code works for me, such as it is. What error are you getting? Here's the (slightly amended) ts:
declare var require: any;
export class LoadConfigurationService {
fs: any;
public data: string;
constructor() {
this.fs = require('fs');
this.data = this.fs.readFileSync('input.txt').toString();
}
}
const obj = new LoadConfigurationService();
console.log(obj.data);
Run this through tsc v1.8.7 produces:
"use strict";
var LoadConfigurationService = (function () {
function LoadConfigurationService() {
this.fs = require('fs');
this.data = this.fs.readFileSync('input.txt').toString();
}
return LoadConfigurationService;
}());
exports.LoadConfigurationService = LoadConfigurationService;
var obj = new LoadConfigurationService();
console.log(obj.data);
Run this with a suitable input.txt (consisting of "File Contents", for me) in the local directory and get:
$ node temp.js
File Contents
Possible problems
There are a couple issues I can see that might get in your way.
The code depends on the native node fs, not "file-system": "^2.2.1"
The worth of the referenced npmjs library aside, you are invoking the native fs library.
Don't require a dependency inside a constructor.
Dependencies for objects is a problem and worth reading about, but this is not a good way to handle it. fs should be immutable, so there's no advantage to requiring it each time the object is constructed. Just one line at the top of the file will do:
const fs = require('fs');
fs inside Angular?
I'm not sure what the snippet has to do with Angular, but if this code is getting webpacked or browserified things will become difficult. fs is for file system access and bundling that into the browser will not end well.

Resources