I am downloading a file from the web, I need to save him in the file cabinet, but when I save it its an empty file (0kb).
let response = https.get({
url: url
});
log.debug('response', JSON.stringify(response.body)) //getting the file content
let fileContent = response.body;
let decodedStr = fileToBase64(fileContent); // get base64 content
let createFile = file.create({
name: "test.csv",
fileType: file.Type.CSV,
content: decodedStr,
folder: 1000
});
createFile.save();
//get base 64
function fileToBase64(stringInput) {
return encode.convert({
string: stringInput,
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64
});
}
still gets an empty csv file.
I suspect if it base64Encoded the file type should not be CSV but file.Type.PLAINTEXT
Related
So I am trying to print a Base64 file but im not sure why it doesn't print the file.
function convertToBase64() {
var selectedFile = document.getElementById("inputFile").files;
if (selectedFile.length > 0) {
var fileToLoad = selectedFile[0];
var fileReader = new FileReader();
var base64;
fileReader.onload = function (fileLoadedEvent) {
base64 = fileLoadedEvent.target.result;
const pdfBlob = new Blob([base64], { type: "application/pdf" });
const url = URL.createObjectURL(pdfBlob);
printJS({
printable: url,
type: "pdf",
base64: true
});
};
fileReader.readAsDataURL(fileToLoad);
}
}
I pass it a pdf file that I select and convert it to Base64.Now I want to print the Base64 using Print.js but I can't make it work.
Your code isn't actually passing the base64 data to the print function, but instead, a URL.
If you want to keep your current code, just remove the base64 flag from the print params.
printJS({
printable: url,
type: 'pdf',
});
Otherwise, you could instead just pass the base64 var to the print function without creating the blog and url, the print library will handle that for you.
Ex.:
Assuming base64Data is a variable with valid base64 data.
printJS({
printable: base64Data,
type: 'pdf',
base64: true
});
I am working on a project where I have to upload an image as form data along with other text fields. I have my file in Base64 string at first, then I convert it into a file before uploading it to the server.
const data = await fetch(base64String);
const blob = await data.blob();
const file = await new File([blob], 'avatar', { type: 'image/png' });
I logged the base64String in the client side before uploading it to the server. Then I upload file to the server as a File. Before saving it to MongoDB when I log it as a base64 string again in the server side, I see my string is not the same as before. I feel like while converting the base64 to file in the client side I am doing something wrong. Help me out please.
I have figured out my problem. When I take image file input from my computer I get a base64 string like below -
dataimage/jpegbase64/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA...
But, when I convert it back into a file it expects a string like below -
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA....
So, basically, I had to trim the string accordingly to match the expected format and wrote a base64 to file conversion function following this answer.
Here is my function to convert a base64 string to an image file
export function getFileFromBase64(string64:string, fileName:string) {
const trimmedString = string64.replace('dataimage/jpegbase64', '');
const imageContent = atob(trimmedString);
const buffer = new ArrayBuffer(imageContent.length);
const view = new Uint8Array(buffer);
for (let n = 0; n < imageContent.length; n++) {
view[n] = imageContent.charCodeAt(n);
}
const type = 'image/jpeg';
const blob = new Blob([buffer], { type });
return new File([blob], fileName, { lastModified: new Date().getTime(), type });
}
I am trying to download and save a large zip file. The zip file is possibly larger than the heap, so I want to use a stream to avoid java.lang.OutOfMemoryError: Java heap space error.
Also, the large zip file is generated on request, so I would like to delete the file after downloading it.
My current code is
#POST
#Path("/downloadLargeZip")
public Response largeZip() throws FileNotFoundException {
File file = generateZipFile(); // generates zip file successfully
FileInputStream input = new FileInputStream(file);
StreamingOutput so = os -> {
try {
int n;
byte[] buffer = new byte[1024];
while ((n = input.read(buffer)) >= 0) {
os.write(buffer, 0, n);
}
os.flush();
os.close();
} catch (Exception e) {
throw new WebApplicationException(e);
}
};
return Response.ok(so).build();
}
My current client-side code is
import { saveAs } from 'browser-filesaver/FileSaver.js';
save() {
this.http.post<any>('url', '', { observe: 'response', responseType: 'blob'})
.subscribe(res => {
this.downloadFile(res);
});
}
downloadFile(response: any) {
const contentDisposition = 'attachment; filename="KNOWN_FILE_NAME"'; // response.headers('content-disposition'); - response object has no headers
// Retrieve file name from content-disposition
let fileName = contentDisposition.substr(contentDisposition.indexOf('filename=') + 9);
fileName = fileName.replace(/\"/g, '');
const contentType = 'application/zip'; // response.headers('content-type');
const blob = new Blob([response.data], { type: contentType });
saveAs(blob, fileName);
}
I have a few problems with my code:
Using dev tools to check the response, it has no headers (normalizedNames is a map with no entries) or data.
Checking the saved zip file, I can't open it using WinRAR. The error is The archive is either in unknown format or damaged.
Trying to open the zip file with Notepad++, the content is the text undefined.
The JSON representation of the response is
{
"headers":{
"normalizedNames":{
},
"lazyUpdate":null
},
"status":200,
"statusText":"OK",
"url":"URL",
"ok":true,
"type":4,
"body":{
}
}
Although the body does contain data {size: 2501157, type: "application/json"}.
Please ignore the number (I am guessing it's the zip file size in bytes, the actual file will be much larger).
What am I doing wrong? How can I read the stream and save the generated zip file?
I think the issue is in my downloadFile function, but I don't know what to change there.
Any help would be appreciated.
I needed to completely change the way I approached the issue.
The server will now generate the file and return a URI for the client. The client will then download the file via given URI.
Server code
#POST
#Path("/create")
public Response createLogs(String data) {
String fileName = generateFileAndReturnName(data);
if (fileName != null) {
return Response.created(URI.create(manipulateUri(fileName))).build();
}
return Response.status(500).build();
}
Client code
save() {
this.http.post<any>(this.baseUrl + '/create', this.data, { observe: 'response'}).subscribe(postResponse => {
if (postResponse.status !== 201) {
this.logger.error('Failed.');
return;
}
postResponse.headers.keys(); // lazy init headers
const uri = postResponse.headers.get('location');
if (!uri) {
this.logger.error('URI not present.');
return;
}
const link = document.createElement('a');
link.href = uri;
link.setAttribute('download', 'fileName.fileExtension');
document.body.appendChild(link);
link.click();
if (link.parentNode) {
link.parentNode.removeChild(link);
}
});
}
Working fine now with 40GB file (32GB RAM, so file is definitely bigger than any allocated heap).
I have a page to download a file from the Postgres database. Now I can hit the following URL to view the file content present in the database(stored as bytes)-HTTP://sandbox4.wootz.io:8080/api/blob/1/UploadFile/hope%20real.txt
Since the data is stored in a column of type bytes(byte array) when I click the download button it downloads the file and when I see its contents it is displayed as a byte array.
file.txt(contents)
[\x58595a5052415445454b3123473b4c534e44204e474f49574853474849444748445348474d70253335]
download functionality
axios({
url: 'api/store/blob/UploadFile/' + data.chosenfile,
method: 'GET',
headers: {'session_id': data.sessionid},
responseType: 'arraybuffer'
}).then(response => {
console.log(response.data); //displays nothing (empty)
var fileURL = window.URL.createObjectURL(new Blob([response.data]));
console.log('fileURL is'+fileURL)
var fileLink = document.createElement('a');
console.log('fileLink is'+fileLink)
fileLink.href = fileURL;
fileLink.setAttribute('download', data.chosenfile);
document.body.appendChild(fileLink);
fileLink.click();
)
console.log of the response object
{"data":{},"status":200,"statusText":"OK","headers":{"access-control-allow-origin":"*","connection":"keep-alive","content-length":"86","content-type":"text/html; charset=utf-8","date":"Mon, 06 Jul 2020 18:22:23 GMT","etag":"W/\"56-Vaz0hG1/FIgtEurgvK+wOU+4F4M\"","x-powered-by":"Express"},"config":{"url":"api/store/blob/UploadFile/hope real.txt","method":"get","headers":{"Accept":"application/json, text/plain, */*","Access-Control-Allow-Origin":"http://localhost","session_id":"c5b3b878-771e-4472-84eb-6de15686effa"},"transformRequest":[null],"transformResponse":[null],"timeout":0,"responseType":"arraybuffer","xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1},"request":{}}
Uploadfile part of my code(this is how the files was uploaded to database)
function readFileAsync(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
var base64Url = reader.result;
console.log(base64Url) //ENITRE BASE64 URL
resolve(base64Url.substr(base64Url.indexOf(',') + 1)); //will return only the base64string part from the base64 url
};
reader.onerror = reject;
reader.readAsDataURL(file);
})
}
async function uploadFile(path, data) {
try {
let base64string = await readFileAsync(data.chosenfile);
console.log('base64 content is'+ base64string)
let response = await axios({
method: 'post',
url: 'api/store/blob' + path,
headers: {'session_id': data.sessionid},
data: {"id":data.chosenfile.name, "file": base64string }
});
if (response.status == 200) {
console.log(response.status);
}
return response.data;
} catch (err) {
console.error(err);
}
}
what am i doing wrong? why am i getting the file contents as [\x58595a5052415445454b3123473b4c534e44204e474f49574853474849444748445348474d70253335] ? What should I do to get the actual file's content in the downloaded file?
NOTE:With respect to the upload part, I am using the same strategy for all kind of files(excel documents,txt files etc) which is encoding it to base64 encoded string before passing it in the axios post payload.Now this payload is passed to another project called data-manager (interacts with postgres database).so when this data-manager project recieves the payload that i sent, it converts it to bytes [] before inserting to the table column of type bytea.So ultimately when i download any file from this table i will get the file contents also in bytea format.
Your file is a correct ASCII text file with content [\x58595a5052415445454b3123473b4c534e44204e474f49574853474849444748445348474d70253335] literally.
That you get this content when you download it is perfectly fine, since it's what this file's content is.
What you want is to parse that content from the Hex representation they used to an actual ArrayBuffer to finally read that again as UTF-8 text (or any encoding respecting ASCII).
This has to be done after you do download the file and read it as text.
You first extract the actual bytes sequence as Hex from that [\x - ] wrapper, then you split the resulting string at every two chars to get hex values of every bytes, and finally you parse it into an Uint8Array to get back the original data:
// for StackSnippet we need to hardcode the response
// OP would have to make its request return that string
const response = { data: String.raw`[\x58595a5052415445454b3123473b4c534e44204e474f49574853474849444748445348474d70253335]` };
// .then( (response) => {
const encoded_text = response.data;
// remove leading "[\x" and final "]"
const encoded_data = encoded_text.slice( 3, -1 );
// split at every two chars, so we can get 0xNN, 0xNN
const hex_bytes = encoded_data.match( /.{2}/g );
// as numbers (0 - 255)
const num_bytes = hex_bytes.map( (hex) => parseInt( hex, 16 ) );
// wrap in an Uint8Array
const view = new Uint8Array( num_bytes );
// from there you can generate the Blob to save on disk
download( new Blob( [ view ] ), "file.txt" );
// but if you want to read it as UTF-8 text, you can:
const as_text = new TextDecoder().decode( view );
console.log( as_text );
// } );
function download( blob, filename ) {
const anchor = document.createElement( "a" );
anchor.href = URL.createObjectURL( blob );
anchor.download = filename;
anchor.textContent = "click to download";
document.body.append( anchor );
}
I'm getting excel data encoded as base64 string from backend. I want to decode this data and download the excel file in the browser. I'm using vuejs as my frontend. Also if I were to show this data in table format on the frontend, how can I go about doing that? Thanks in advance for the response.
This is what I have tried-
public downloadfile() {
var data = window.atob("string");
this.save("file", data, ".xls");
}
public save(name: any, data: any, type: any) {
var bytes = new Array(data.length);
console.log("here", bytes);
for (var i = 0; i < data.length; i++) {
bytes[i] = data.charCodeAt(i);
}
data = new Uint8Array(bytes);
var blob = new Blob([data], { type: type });
console.log(blob);
let objectURL = window.URL.createObjectURL(blob);
let anchor = document.createElement("a");
anchor.href = objectURL;
anchor.download = name;
anchor.click();
URL.revokeObjectURL(objectURL);
}
I have a run button on clicking that downloadfile runs. and a file.txt gets downloaded. What am I doing wrong here? If I rename the file format to xls, that file shows correct data.
You need a browser Javascript library that understands excel format. I have used sheetjs with good success in the past.