I'm using antd upload, and I would like to change the upload data dynamically depending on the file name. Currently, this works fine for single file uploads, see below:
function MyUpload() {
const [fileName, setFileName] = useState();
return (
<Upload
action='...'
uploadType='...'
data={{
fileName: fileName
}}
beforeUpload={(file: File, _) => setFileName(file.name)}
directory={false}
>
);
}
The problem occurs when I try creating a directory upload field. If I change directory to true above, then beforeUpload is called several times for each file, but the only fileName set is that of the last file processed. Therefore, all the different files will have the upload data of the last file processed.
I was wondering if there was a way to use this approach or perhaps a better approach to set values in the data property that reflect the current file being uploaded, in a dynamic way.
Thanks in advance
Related
I am able to open and stream the file no issue by using the following, however I need to be able to use the file information that is stored inside the bucket.
const db = connection.connections[0].db
const bucket = new mongoose.mongo.GridFSBucket(db, {
bucketName: bucketName
});
bucket.openDownloadStreamByName(filename).pipe(res)
For example I would like to be able to set the following
res.setHeader('Content-Type', (TYPE)),
res.setHeader('Content-Length', (LENGTH)),
I am wondering the following above allows options however I don't know if the pipe stops us from setting the content-type and length after it starts piping.
According to docs, no you can't get file info from stream but in source code seems you can.
According to this and this, you could get contentType by accessing
bucket.openDownloadStreamByName(...).s.files[0].contentType
or
bucket.openDownloadStreamByName(...).s.file?.contentType
I have an excel file stored in src folder. I want to use react to read the excel file directly instead of uploading a file using input field and show the object array to the console, does anyone know how to do it? Any reference link about that? I saw a lot about uploading an excel file and output the data, but I don't want to upload the file. I want to import the file directly or fetch data from the file. Let me know if you know how to do in react. Thanks.
You could use FileReader API. Here's a link to similar question. You could parse/read the excel file using this package.
A little suggestion, would be to use .csv or .json files instead of .xlsx files, if you are only dealing in data.
fetch(excelFile).then((res) => res.arrayBuffer())
.then((ab) => {
const wb = XLSX.read(ab, { type: "array" });
const sheetname = wb.SheetNames[0]
const ws = wb.Sheets[sheetname]
const json = XLSX.utils.sheet_to_json(ws,{header: 1,defval:''})
console.log(json)
Here excelFile is file location, you may include your excel file location, Then json contain excel data.
Thanks.
I use Excel data as a data source. I want to create slug dynamically and use Gatsby docs as an example. https://www.gatsbyjs.com/docs/tutorial/part-seven/
But this does not work, because I don't use Markdown files. I changed 'MarkdownRemark' to 'ExcelData'.
exports.onCreateNode = ({ node, getNode }) => {
if (node.internal.type === `ExcelData`) {
const fileNode = getNode(node.parent)
console.log(`\n`, fileNode.relativePath)
}
}
When You look at Gatsby docs, code print to the terminal two markdown files relative paths:
pages/sweet-pandas-eating-sweets.md
pages/pandas-and-bananas.md.
Mine code prints out same path multiple time, because there is only one Excel file.
I try to change the code and use data that is in an Excel file.
const fileNode = getNode(_9)
But this does not work and I get an errors like:
"gatsby-node.js" threw an error while running the onCreateNode lifecycle:
_9 is not defined
const fileNode = getNode(node._9)
Cannot read property 'relativePath' of undefined
Is it possible to change (node.parent) or not?
I assume you're using https://www.gatsbyjs.com/plugins/gatsby-transformer-excel/ already?
Gatsby has a new filesystem routing API that means creating routes like this is much easier called the File System Routing API — this links to the section on Collection Routes which automatically creates pages from every node in a collection without needing to create slugs manually in gatsby-node.js.
E.g. your type is ExcelData so you'd just need to create a collection route component at src/pages/{ExcelData.title}.js (assuming your spreadsheet has a field named title) to create pages for all your spreadsheet rows.
This works with any type and any field.
I have a custom form using a "managed_file" which uploads to temp folder. Programmatically, I then load that file and move it to its permanent storage (overwriting any existing file with the* name) e.g.
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
All of this works (i.e. the file physically is moved into the correct place with correct name); however, the file displayed in the listings (i.e. /admin/content/files) still shows the incorrect temporary folder as the URI.
Basically the file in the listings page seems to be showing the original filepath and name* of a previously successfully moved* file.
If I load this file with incorrect URI, i.e. using the incorrect temp path, the data loads, but then will not have a file info (as it doesn't exist. Also clicking the filename by browser under listings will show page not found and the URL showing the old URL i.e. /system/temporary?file=XYZ.pdf).
If I load this file by correct URI, i.e. using the correct destination path, file not found - same if I go to the path directly in the browser.
It appears the managed file doesn't know it was moved. How to resolve this bug?
The docs for FileSystem::move say "Moves a file to a new location without database changes or hook invocation."
So you are going to need to update the file entity with the new values..
Try this, untested:
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$newFileName = $this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
// Set the new file path on the file entity.
$upfile->setFileUri($newFileName);
// Set the file to permanent if needed.
$upfile->setPermanent();
// Save entity with changes.
$upfile->save();
I did not test this though.
You can check the functions on the file entity in the docs here
It turns out the class based methods do not update the database
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21FileSystem.php/function/FileSystem%3A%3Amove/8.9.x
The procedural version does
https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/file_move/8.9.x
I'm building an app which needs to take uploaded files and put them in separate directories for thumbnails and fullsize images. But $config['upload_path'] = './uploads/'; only allows me to select one upload path.
How do I define two or more upload paths?
Actually all you need to do is "re-initialize" the upload class. Codeigniter does not allow you to call the class twice with new parameters (it ignores the second request), however you can tell the class to manually load new parameters. Here are the basics: (notice the line "$this->upload->initialized($config)" This is the key.
// this is for form field 1 which is an image....
$config['upload_path'] = './uploads/path1';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';
$this->upload->initialize($config);
$this->upload->do_upload($fieild_1);
// this is for form field 2 which is a pdf
$config['upload_path'] = './pdfs/path2';
$config['allowed_types'] = 'pdf';
$config['max_size'] = '300';
$this->upload->initialize($config);
$this->upload->do_upload($fieild_2);
I wrote an entire article about it here:
http://taggedzi.com/articles/display/multiple-file-uploads-using-codeigniter
You can change any of the allowed parameters in your second initialize script so that your second file can be of a completely different makeup. You can do this as many times as you like you just have to re-initialized for each file type. (You can even setup a config array and loop through if you like...)
Hope this helps.
You're conflating two issues here. You need to further decompose the problem into discrete tasks.
First of all, you need to set the appropriate upload directory. On my site, each user is directed to their own upload directory:
/images/member/1
/images/member/2
/images/member/3
My controller sets the upload directory dynamically, based on user id
$config['upload_path'] = "/images/member/$user_id";
Second, you need to process your uploaded file, creating resized and thumbnail images. My image processing library uses the same path that I passed to $config['upload_path'] as its root directory, and places its output into subdirectories relative to that dynamic root:
/images/member/1/resized
/images/member/1/thumbnails
My site is actually a little more complex than that. But the point is that setting $config['upload_path'] dynamically lets you have as many upload paths as you want.
The short (and disappointing) answer is: CodeIgniter's file uploading class was designed to accept 1 uploaded file per form.
The long answer is somewhere around here.