Error downloading XLSM file from angular application - javascript

I have an XLSM (macro enabled with sheet level formatting) file in my repository. I have used 'xlsx-populate' node library to read the file, add rows and save it in the repository successfully. I pass the work book to front end, setting the headers and MIME type for XLSM file, the file gets downloaded but upon trying to open it says 'Excel cannot open the file because the file format is not valid. Verify that the file has not been corrupted and that the extension matches the format of the file'. The same flow is successfully working for an XLSX file though. Is it possible that angular supports XLSM file download (possibly) with any alternative library? Is it the way in which the content is being sent that needs alteration? I am also open to any alternative approaches/suggestions.
MIME type for XLSM: application/vnd.ms-excel.sheet.macroEnabled.12
Code snippet:
this.content = XlsxPopulate.fromFileAsync(__dirname + "myFile.xlsm");
downloadFile(req,res) {
res.setHeader('Content-Type', xlsmMimeType);
res.setHeader('Content-Disposition', 'attachment; filename=myFileName');
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
res.send(this.content)
}

Related

Android webview - how to fetch a file from external storage

I have a mobile app that wraps around the web-app, using webview.
The web-app has a button to open a large .zip file (e.g. 100 MB).
The user clicks a button, and selects a .zip file.
This triggers an onChange function with a variable of type File (Blob), which includes attributes like:
file name
file size
file type (application/zip)
The javascript code then parses the .zip file, extracts specific data within it and uses it within the web-app.
This works well within the web-app, when the app is called via the Chrome browser.
For example when operated in chrome browser on an Android phone, I can pull the .zip file and open it in the web-app.
I want to do the same but using the mobile app.
I am able to pick up the .zip file using a File Chooser, and pass it to Webview but I have problems to fetch the file from the Javascript code.
For reference, I am able to pass an image, by creating a data_uri using stringBuilder and passing the content (as data:image/jpeg;base64).
But the zip file is much larger.
When calling fetch(fileUri) from the Javascript side I'm getting errors.
I'm using the following uri
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
The fetch succeeds but returns a blob with size of 165 (i.e. not the actual size of the file) which hosts the error message:
{
"error": "Not Found",
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}
The program flow is like so:
I select a .zip file via FileChooser.
In onActivityResult, the uri value is /document/msf:12858 (seen via uri = intent.getData();)
The uri needs to be mapped into a real path file url, such that the fileUrl will be passed to webview.
Webview will then fetch the file using the fileUrl.
I searched how to get the real path file url when selecting a file with FileChooser, and found
this, and this links.
I wasn't able to get the real file path, so I decided to read the file and write it to another location, so I can get a file path. (this is not efficient and done just to check the functionality).
I create the new file using the following code:
InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);
I don't see any errors when creating the file, and when creating the file, the number of bytes that are read and written to the new file are as expected.
For file2, I get a value of:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
Then, within the Javascript code I fetch this file path.
But I'm getting a Blob with the "file-not-found" content as above.
So:
How can I verify that the file is indeed created and that the path can be fetched from webview?
How can I get the real file path of the original selected file, so I don't have to read and write the original file to new location just to get the file path?
Thanks
I was able to get the file from external storage by doing the following steps:
create an initial uri (uri1)
The uri is created by:
creating a temporary file (file1) in the storage dir via
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
I'm not sure why a temporary file need to be created but if I don't create a file I cannot get the uri.
createFile3
get the uri via
Uri uri1 = FileProvider.getUriForFile(context, "com.example.android.fileprovider", file1);
create an intent with the following attributes:
Intent.ACTION_OPEN_DOCUMENT
category: Intent.CATEGORY_OPENABLE
type: "application/zip"
extra attribute: fileIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1);
this opens a dialog box for selecting openable zip files in the Downloads directory,
after the file is selected, a new uri (uri2) is created that includes the name of the selected file.
extract the name of the file via
String fileName = getFileName(context, uri2);
create the dirPath by appending the filename
dirPath = "/data/user/0/com.example/" + fileName;
if the dirPath does not exist (first time), write the file to its dirPath location.
on successive ocassions dirPath exists, so there is no need to re-write the file.
open the file with regular Java means, e.g. via
ZipFile zip = new ZipFile(dirPath);

How to read contents off a zip file from google cloud storage (GCS) in Postman javascript

In postman response, the output is a URL that contains a https link to google cloud storage which contains a zip folder. This . zip folder contains an excel and a pdf file.
I am looking for one of these solutions.
Either use javascript to download the zip folder, parse it and validate the contents in the folder. i.e assert to ensure the content of the zip folder contains an excel and a pdf file.
Make a GET request directly to gcs API via encoded url to get the contents of the zip folder. At the moment I can get to gcs cloud API, it seems to provide me with metadata, not the contents of the zip folder
For the 2nd solution, I have tried using this URL to get to the GCS
https://www.googleapis.com/storage/v1/b/gcs-bucket-service/o/361b6d18-3881-49ed-994b-442574%2Freport_1.zip
This provides the metadata
I would be happy for either of the solutions to work
You can't have an AJAX request open the download prompt since you physically have to navigate to the file to prompt for download. Instead, you could use a success function to navigate to download.php. This will open the download prompt but won't change the current page.
$.ajax({
url: 'download.php',
type: 'POST',
success: function() {
window.location = 'download.php';
}
});

Cannot download .kmz file extension file - due to extension configuration

Error screeshot
Here is the code that I am using
var pdfPath = $('#urlHiddenField').val() + "Documents/UserSignedAgreements/" + encodeURIComponent(data);
window.open(pdfPath, '_blank');
What I am doing is getting the filename from database and file is saved on project folder. My all types of document type (jpg, png, txt, docx, pdf..etc) all are working, BUT FILE TYPE (.kmz) extension is not working.
There is an option on UI with the filename to click it and in new tab some documents get open while some get downloaded with above code. Need help how to go with this file extension.

retrieve a specific file and store

I have some php files which I am hosting on a web hosting site.I want to take a specific file from user's desktop and upload it to my server on click of a button.The user should not specify the file path and the file path is known to me.
For eg:
php code
copy("C:\Users\Admin\Desktop\IMG_20141118_213032.jpg",
"/home/u131954735/public_html/uploads/new.jpg");
where C:.... gives the path of the image file on my Desktop and /home/u13.. gives the path where I want to store the file on server as new.jpg.
But on running the above code gives :
Warning: copy(C:\Users\Admin\Desktop\IMG_20141118_213032.jpg): failed
to open stream: No such file or directory in
/home/u131954735/public_html/upload.php
How to rectify this problem?
I think that you can't copy a file from user's desktop with the url (for security problems).
You can upload file sending it to server: http://www.w3schools.com/php/php_file_upload.asp

Check actual file type in node.js

I want to prevent people from, say, uploading a movie file or shell script by just adding a jpg extension to my avatar upload endpoint. I haven't written the backend to upload script in a long time but I remember PHP being able to tell me the actual file type, not just the type based on the file extension. I can also check this purely on the front-end JS. Or in Java there's http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType%28java.nio.file.Path%29
The issue is in vanilla Node and using a bunch of mime related modules including mmmagic are just returning the mime type based on the file extension. For example, I removed the gif extension on a gif file and changed it to txt and both Node and mmmagic just return text/plain.
In Java, I was using Tika, which is a mime type detector tool. Turns out, there is nodejs bridge for it, node-tika.
To use
npm install node-tika
and
var tika = require('tika');
tika.type('test/data/file.pdf', function(err, contentType) {
console.log(contentType); // Logs 'application/pdf'.
});

Categories