How to add custom metadata in PDF file using react js? - javascript

I'm taking input as a PDF file and using javascript to add custom metadata, but I'm not getting a satisfactory result.
Below is a sample method code that I used to add custom metadata that is first converted to blob type and then added, but when we convert its blob data to base64 and download the file and check the properties, we cannot find it.
const blobToBase64 = (blob: any) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
const updatePDFMetaData = (file: any, metadata: any) => {
let convertBlobToBase64: any;
const selectedFile = file;
const reader = new FileReader();
reader.readAsArrayBuffer(selectedFile);
reader.onload = async (event:any) => {
const fileBuffer: any = event?.target?.result;
const blob: any = new Blob([fileBuffer], { type: selectedFile.type });
Object.keys(metadata).forEach((key: any) => {
blob[key] = metadata[key];
});
convertBlobToBase64 = await blobToBase64(blob);
console.log("convertBlobToBase64", convertBlobToBase64);
};
};

Related

converting image to base64 - image becomes invisible

I'm trying encode an image to base64, (so I can later send it this way to a backend server). Everything seems to work until I use JSON.stringify() on the object that has the encoded image in it.
I think It gets lost in the JSON.stringify() and I can't seem to find a solution. I've been working for weeks on this issue and I couldn't find an answer anywhere. Please help!
const [baseImage, setBaseImage] = useState('');
const [baseImageCorrect, setBaseImageCorrect] = useState('');
const convertBase64 = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.onerror = (error) => {
reject(error);
console.log(error);
};
});
};
const uploadImage = async (e) => {
const file = e.target.files[0];
const base64 = await convertBase64(file);
const base64RemovedType = base64.split(',')[1];
setBaseImage(`${base64RemovedType}`);
};
useEffect(() => {
setBaseImageCorrect(baseImage);
console.log('current:' + baseImageCorrect);
//prints out a long string with the RIGHT information
}, [baseImage, baseImageCorrect]);
const EncodedImage = JSON.stringify({
fileBase64: (baseImageCorrect, { encoding: 'base64' }),
});
console.log(EncodedImage)
//PRINTS THIS: "fileBase64":{"encoding":"base64"}} , without the encoded image string
I am assuming u need the key baseImageCorrect and encoding key at the same level.
Use this instead:
const EncodedImage = JSON.stringify({
fileBase64: {baseImageCorrect, encoding: 'base64' },
});

Wait for function to finish reading excel file

I want to read an excel file and return the data in json format. When I call 'readExcelSheet' function on button click, it returns 'undefined' as function hasn't been finished reading the excel data. On subsequent click, data does return properly. I want to wait for this function until it read complete data.
constructor(private httpClient: HttpClient) {
}
readExcelSheet() {
let dataJson;
this.httpClient.get(this.filePath, { responseType: 'blob' })
.subscribe((data: any) => {
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
// reader.readAsBinaryString(e.target.files[0]);
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
/* grab first sheet */
const wsname1: string = wb.SheetNames[0];
const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];
dataJson = XLSX.utils.sheet_to_json(ws1);
};
reader.readAsBinaryString(data);
});
return dataJson;
}
When you call subscribe, the code executes this line asynchronously (ie: skips over this line and go to the return immediately). Use lastValueFrom in an async-await function instead.
Try doing this:
async readExcelSheet(){
let dataJson;
const data = await lastValueFrom(this.httpClient.get(this.filePath, { responseType: 'blob' }))
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
/* grab first sheet */
const wsname1: string = wb.SheetNames[0];
const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];
dataJson = XLSX.utils.sheet_to_json(ws1);
};
reader.readAsBinaryString(data);
return dataJson;
}
Try using ASYNC & AWAIT in your functions
async readExcelSheet()
Try to use toPromise instead of subscribe and then you can return the function.
You can then try to use Promise.resolve() to resolve the dataJson.
constructor(private httpClient: HttpClient) {
}
readExcelSheet() {
return this.httpClient.get(this.filePath, { responseType: 'blob' })
.toPromise().then((data: any) => {
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
// reader.readAsBinaryString(e.target.files[0]);
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
/* grab first sheet */
const wsname1: string = wb.SheetNames[0];
const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];
Promise.resolve(XLSX.utils.sheet_to_json(ws1))
};
reader.readAsBinaryString(data);
});
}

How to make a clipboard stream from guacamole-common.js.?

I am using Guacamole.client.createClipboardStream for creating a clipboard stream and send write the stream on paste event but, the remote clipboard is still empty.
const stream = client.createClipboardStream("text/plain");
stream.sendBlob(data);
I had the same issue, but then found that per the Guacamole Common Js spec, the OuputStream.sendBlob method expects a Base64 encoded string representing the blob.
Here's a little snippet from my quite early code to do this
const blobToBase64 = (blob) => {
return new Promise((res, _) => {
const reader = new FileReader();
reader.onloadend = () => res(reader.result);
reader.readAsDataURL(blob);
});
}
const sendBlobBasedOnMimeType = async (item, mimeType) => {
const blob = await item.getType(mimeType);
const blobAsDataUrl = await blobToBase64(blob);
const blobAsB64 = blobAsDataUrl.split(",")[1];
console.log("size of b64 blob", blobAsB64.length);
const stream = guac.current.createClipboardStream(mimeType, "remote");
stream.onack = () => {
stream.sendEnd();
}
stream.sendBlob(blobAsB64);
}

How can I read the data in the excel file with reactjs or javascript using the path to the file

I want to read the contents of the file directly by using the file path. I can do this by having the file selected. But I don't know how to do it using the direct file path. I could not find any examples or sources for this. Below is how I read the file by selecting it from the input.
import * as XLSX from 'xlsx';
var items = [];
readExcel = (file) => {
const promise = new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = (e) => {
const bufferArray = e.target.result;
const wb = XLSX.read(bufferArray, { type: "buffer" });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const data = XLSX.utils.sheet_to_json(ws);
resolve(data);
};
fileReader.onerror = (error) => {
reject(error);
};
});
promise.then((d) => {
this.items = d;
console.log(this.items)
// fill dictionary
this.dictionary = Object.assign({}, ...this.items.map((x) => ({ [x.PartNumber]: x.Cost })));
console.log(this.dictionary)
});
};
<input
type="file"
onChange={(e) => {
const file = e.target.files[0];
this.readExcel(file);
}}
/>
I beleive it should work:
const req = new XMLHttpRequest();
req.responseType = "arraybuffer";
req.open("GET", "https://.../MyExcelFile.xlsx", true);
req.onload = () => {
const bufferArray = req.response;
const wb = XLSX.read(bufferArray, { type: "buffer" });
...
I couldn't find a direct read operation. I converted the excel file to json format and got my job done.

What is the correct fetch body in React with FileReader

I have a React app which gets data from an upload. I want to send the data (mostly CSV's) row by row to my API. The problem is that I cannot get the correct value.
const uploadLocalFile = (file) => (dispatch) => {
const reader = new FileReader()
reader.onload = evt => {
fetch("some/api/here",
{
credentials: "same-origin",
method: "POST",
body: //file, evt.target.result ?? <---
})
}
reader.readAsText(file)
alert("done.")
}
file is the whole file, evt.target.result is not allowed in react? Is evt.currentTarget forbidden by fetch?
What do you mean by "not allowed in react"? Passing this function as the handler for your file input should work:
handleSelectFile = (event) => {
const file = event.currentTarget.files[0]
const reader = new FileReader()
reader.onload = (event) => {
const content = event.target.result
// do whatever you want do do with `content`
}
reader.readAsText(file)
}

Categories

Resources