Read Uint8Array buffer from Collection and download as pdf - mongodb

I saved a pdf file in a collection using this function:
/*** client.js ***/
// asign a change event into input tag
'change input' : function(event,template){
var file = event.target.files[0]; //assuming 1 file only
if (!file) return;
var reader = new FileReader(); //create a reader according to HTML5 File API
reader.onload = function(event){
var buffer = new Uint8Array(reader.result) // convert to binary
Meteor.call('saveFile', buffer);
}
reader.readAsArrayBuffer(file); //read the file as arraybuffer
}
/*** server.js ***/
Files = new Mongo.Collection('files');
Meteor.methods({
'saveFile': function(buffer){
Files.insert({data:buffer})
}
});
How can I read it again from the collection and provide a download link that the user can download the file as a pdf and save it on the local computer?

It depends on what the data type ends up to be on the front-end when you see that document record in your MiniMongo collection. What you want to do is to convert that Uint8Array data to a base64-encoded data URL and provide a Download PDF link after you get the data in the browser.
Meteor does not support serving files from the server out of the box, so you'll likely have to publish that file's blob via mongo->minimongo publication/subscription mechanism and then use the HTML data-uri API to get it like I've just described.

Related

How to upload file to mongodb on mongoose using nestJS?

Hello pls do somebody know how to upload file to MongoDB (mongoose) using nestJS ??
I already have the ability to #Post upload file to my nestJS projet and #Get, but know I wanna post to mongodb using mongoose, pls help
I don't recommend to store images on your database but you can do this:
async function saveFile(file: Express.Multer.File){
//Convert the file to base64 string
const fileB64 = file.buffer.toString('base64')
//userModel is a mongoose model
//Store the string
await this.userModel.create({file: fileB64})
}
async function getFile(userId: string){
//Get user from database
const user = await this.userModel.findOne({_id: userId}).lean()
if(!user) throw new NotFoundException('User not found')
const file = user.file
//Convert the string to buffer
return Buffer.from(file, 'base64')
}
First you have to convert that file to a string with base64 encoding then you can save that string on your database with the create method or updating a document.
If you want to get that file just search that info in your database and then convert the string to buffer and return it.
Like I said before, I don't recommend this it is better if you upload the buffer to s3 and save the link on your database.
thanks it is worked, but it is only buffer a can't see the image! please is there any others option to get is as image? please here what i'm getting :
{"type":"Buffer","data":[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,72,0,72,0,0,255,225,0,120,69,120,105,102,0,0,73,73,42,0,8,0,0,0,4,0,18,1,3,0,1,0,0,0,1,0,0,0,49,1,2,0,7,0,0,0,62,0,0,0,18,2,3,0,2,0,0,0,2,0,2,0,105,135,4,0,1,0,0,0,70,0,0,0,0,0,0,0,71,111,111,103,108,101,0,0,3,0,0,144,7,0,4,0,0,0,48,50,50,48,2,160,4,0,1,0,0,0,208,2,0,0,3,160,4,0,1,0,0,0,0,5,0,0,0,0,0,0,255,192,0,17,8,5,0,2,208,3,1,34,0,2,17,1,3,17,1,255,196,0,31,0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,255,196,0,181,16,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125,1,2,3,0,4,17,5,18,33,49,65,6,19,81,97,7,34,113,20,50,129,145,161,8,35,66,177,193....
Angular service file
postFile(fileToUpload: File): Observable<any> {
const formaData: FormData = new FormData();
formaData.append('fileKey', fileToUpload, fileToUpload.name);
return this.http.post(`${this.backEndURL}/api/prods/upload/two/tree/`, JSON.stringify(formaData));}
but my backend Nestjs trow error:
[ExceptionsHandler] Cannot read property 'buffer' of undefined +80859ms
TypeError: Cannot read property 'buffer' of undefined

Is there a dart package to decode an ms word document and edit in a flutter application?

I am creating a flutter app which needs to import an ms word document, which already has some bookmarks for it. I need to decode the the word document and edit those bookmarks programatically.
There are packages for decoding xml and excel files like xml: ^3.2.3 and spreadsheet_decoder: ^1.0.0, but I cannot find anything for decoding ms word documents.
I have done this in VBA using this code
Sub UpdateBookmark(BookmarkToUpdate As String, TextToUse As String)
Dim BMRange As range
Set wordDoc = wordDoc_c
wordDoc.ActiveWindow.View.ReadingLayout = False
With wordDoc.Application.ActiveDocument
.Bookmarks(BookmarkToUpdate).range.Text = TextToUse
End With
End Sub
I expect to import the file, decode it and edit at the place of bookmarks. Please help me if you have a way to do this.
I'm glad to inform you that Aspose.Words Cloud Dart SDK has become available recently: https://pub.dev/packages/aspose_words_cloud.
You may do what you want to do with the following code:
// Configure words api client
// You may get AppKey and AppSid here https://dashboard.aspose.cloud/dashboard.
// 150 requests are available for free per month.
var configuration = new Configuration('AppKey', 'AppSid');
var wordsApi = new WordsApi(configuration);
// Upload file to cloud
var localFileContent = await (new File('fileStoredLocal.docx').readAsBytes());
var uploadRequest = new UploadFileRequest(ByteData.view(localFileContent.buffer), 'fileStoredInCloud.docx');
await wordsApi.uploadFile(uploadRequest);
// Change document bookmark
var bookmarkData = new BookmarkData()
..text = 'New bookmark text';
var updateBookmarkRequest = new UpdateBookmarkRequest('fileStoredInCloud.docx', bookmarkData, 'bookmarkName');
await wordsApi.updateBookmark(updateBookmarkRequest);
// Download changed document from cloud
var downloadRequest = new DownloadFileRequest('fileStoredInCloud.docx');
var changedDocument = await wordsApi.downloadFile(downloadRequest);
(new File('fileStoredLocal.docx')).writeAsBytes(changedDocument.buffer.asUint8List(changedDocument.offsetInBytes, changedDocument.lengthInBytes));
Hope it helps, otherwise please feel free to ask additional questions.
Disclaimer: I'm a product manager of Aspose.Words Cloud.

Get undefined variable trying to update the path to an uploaded file within MongoDB using angular-file-upload and MEAN.js

If someone could help me I would be eternally grateful. I have been slamming my head against a brick wall for weeks trying to get images to upload the way it is demonstrated out of the box with the MEAN.js users module. In the generated users module the file is uploaded into a directory and the path to that file is stored in a field in the mongodb document. I can get the file to upload to where it needs to go using multer and the fileupload function. However, I cannot save the path to the field within the document. I cannot figure out how to avoid getting an 'undefined' variable. I've tried creating a $window service and passing data to it as a global variable and a bunch of other things and I'm totally stuck.
I have commented the code below to demonstrate what is going awry in my server controller changeShoePicture function.
// This is the boilerplate code from the mean.js "users" module.
// I can not create a $window service or global variable to store the
// shoe data below so that I can update the shoe.shoeImageURL field
// in MongoDB with path to the successfully uploaded file.
exports.changeShoePicture = function (req, res) {
var message = null;
var shoe = req.shoe;
var upload = multer(config.uploads.shoeUpload).single('newProfilePicture');
var profileUploadFileFilter = require(path.resolve('./config/lib/multer')).profileUploadFileFilter;
console.log('i am here', shoe); // shoe is defined here.
// Filtering to upload only images. This works and proceeds to the else condition!
upload.fileFilter = profileUploadFileFilter;
upload(req, res, function (uploadError) {
if(uploadError) {
return res.status(400).send({
message: 'Error occurred while uploading profile picture'
});
} else {
//shoe image file is successfully uploaded to the location on the server,
// However the following fails because the shoe variable is undefined.
shoe.shoeImageURL = config.uploads.shoeUpload.dest + req.file.filename;
}
});
To make sure I've got this right:
The upload function is being called on your parameters passed by your route, req and res. You set the shoe var from req.shoe.
What are the chances that upload() is messing with your req?
Drop a console.log(req) in right after you call upload and report back

Upload Data to Meteor / Mongo DB

I have a Meteor app and would like to upload data (from csv) to a meteor collection.
I have found:
solutions (e.g. Collectionfs) which deal with file uploads
methods for uploading directly to the underlying mongo db from the shell
references to meteor router - but I am using the excellent iron-router, which does not appear to provide this functionality
My requirement is that the app user be able to upload csv data to the app from within the app. I do not need to store the csv file anywhere within the app file structure, I just need to read the csv data to the collection.
It is possible that I cannot figure out how to do this because my terms of reference ('upload data to meteor') are ambiguous or incorrect. Or that I am an idiot.
ChristianF's answer is spot on and I have accepted it as the correct answer. However, it provides even more than I need at this stage, so I am including here the code I have actually used - which is largely taken from Christian's answer and other elements I have found as a result:
HTML UPLOAD BUTTON (I am not including drag and drop at this stage)
<template name="upload">
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
</template>
JAVASCRIPT
Template.upload.events({
"change #files": function (e) {
var files = e.target.files || e.dataTransfer.files;
for (var i = 0, file; file = files[i]; i++) {
if (file.type.indexOf("text") == 0) {
var reader = new FileReader();
reader.onloadend = function (e) {
var text = e.target.result;
console.log(text)
var all = $.csv.toObjects(text);
console.log(all)
_.each(all, function (entry) {
Members.insert(entry);
});
}
reader.readAsText(file);
}
}
}
})
NB there is a jquery-csv library for Meteor here: https://github.com/donskifarrell/meteor-jquery-csv
I've solved this problem in the past using this gist of mine, together with this code (using the jquery-csv plugin to parse the csv data). This is done on the client side and is independent of using iron-router or not. It would be fairly straightforward to move the insertion code into a Meteor method, uploading the csv file first and then parsing and inserting the data on the server. I've tried that, too, but didn't see any performance improvement.
$(document).ready(function() {
var dd = new dragAndDrop({
onComplete: function(files) {
for (var i = 0; i < files.length; i++) {
// Only process csv files.
if (!f.type.match('text/csv')) {
continue;
}
var reader = new FileReader();
reader.onloadend = function(event) {
var all = $.csv.toObjects(event.target.result);
// do something with file content
_.each(all, function(entry) {
Items.insert(entry);
});
}
}
}
});
dd.add('upload-div'); // add to an existing div, turning it into a drop container
});
Beware though that if you are inserting a lot of entries, then you are better off turning all reactive rerendering off for a while, until all of them are inserted. Otherwise, both node on the server and the browser tab will get really slow. See my suggested solution here: Meteor's subscription and sync are slow

ADO.NET Data Services - Uploading files

I am trying to write REST web service through which our clients can upload a file on our file server. IS there an example or any useful links which I can refer for any guidance?
I haven't seen many examples of POST operation using ADO.NET data services available.
I've uploaded a file to ADO.NET dataservices using POST although I'm not sure whether it's the recommended approach. The way I went about it is:
On the dataservice I've implemented a service operation called UploadFile (using the WebInvoke attribute so that it caters for POST calls):
[WebInvoke]
public void UploadFile()
{
var request = HttpContext.Current.Request;
for (int i = 0; i < request.Files.Count; i++)
{
var file = request.Files[i];
var inputValues = new byte[file.ContentLength];
using (var requestStream = file.InputStream)
{
requestStream.Read(inputValues, 0, file.ContentLength);
}
File.WriteAllBytes(#"c:\temp\" + file.FileName, inputValues);
}
}
Then on the client side I call the data service using:
var urlString = "http://localhost/TestDataServicePost/CustomDataService.svc/UploadFile";
var webClient = new WebClient();
webClient.UploadFile(urlString, "POST", #"C:\temp\test.txt");
This uses a WebClient to upload the file which places the file data in the HttpRequest.Files collection and sets the content type. If you would prefer to send the contents of the file yourself (eg from an Asp FileUpload control) rather than the webClient reading a file using a path to the file, you can use a WebRequest similar to the way that it's done in this post. Although instead of using
FileStream fileStream = new FileStream(uploadfile,
FileMode.Open, FileAccess.Read);
you could use a byte array that you pass in.
I hope this helps.
I'm not 100% sure how to do this directly to a file server per se, but ADO.Net Data Services definitely support something similar to a database. The code below is how a similar goal of putting a file into a database has been accomplished. Not sure how much that will help, but
var myDocumentRepositoryUri = new Uri("uri here");
var dataContext = new FileRepositoryEntities(myDocumentRepositoryUri);
var myFile = new FileItem();
myfile.Filename = "upload.dat";
myFile.Data = new byte[1000]; // or put whatever file data you want to here
dataContext.AddToFileItem(myFile);
dataContext.SaveChanges();
Note: this code is also using Entity Framework to create a FileItem (representation of a database table as an object) and to save that data.