15

I have an upload system and I am trying to supply a sample template for users. I have a template stored locally in a subfolder in assets, I would like to access that in my VueJS component and display a link to it on the page. These are the applicaple parts of the file structure:

├──app
│  └──Components
│     └──Uploader.vue
└──assets
   └──files
      └──Template_Upload.csv

In Uploader.vue I have this line:

<a v-bind:href="item.loc" download>{{item.title}}</a>

And in the export I have this line

data() {
  return {
    item: {title: 'Upload Template', loc: require('../../assets/files/Template_Upload.csv')}
}

This method works if I have an image. Upon clicking on the link, it downloads the image. However, if I use a .csv or a .xlsx file, errors are thrown upon opening the page. I've tried using

import fileTemplate from "../../assets/files/FileTemplate.csv";

As well, and using fileTemplate as the loc property. This also works if I use a picture. But I'm not able to bring in a document. Is this a limitation I can't get past or is there a different method I can try?

I've also gone into Visual Studio (in other words, the .csproj file), and set the Template_Upload.csv Build Action setting is set to "Content" and the Copy to Ouput Directory setting is set to "Copy Always".

These are the resources I have primarily used thus far:

How to import and use image in a Vue single file component?

What are the various "Build action" settings in Visual Studio project properties and what do they do?

Community
  • 1
  • 1
Judd
  • 409
  • 1
  • 3
  • 13
  • You need a CSV loader. Other options include making your web server serve that directory and then the `loc` would just be a typical link – OverCoder Dec 29 '17 at 01:20

8 Answers8

17

For anyone which doesnt want to use webpack, I solved this issue:

  • create a folder called files in public
  • I moved there the files I wanted to download and Voila, WORKED.

enter image description here <a href="/files/book.pdf" download>DOWNLOAD</a>

Cristea
  • 913
  • 10
  • 15
10

Thanks OverCoder, the solution was indeed to add a CSV Loader in order that adds the locally stored files to the webpack server. For anyone else using webpack, I added this module to my webpack.config.js file:

{
    test: /\.(csv|xlsx|xls)$/,
    loader: 'file-loader',
    options: {
        name: `files/[name].[ext]`
    }
}

Then I could reference the file easily like this in my template,

<a href="/files/Template_Upload.csv" download>File Template</a>

or this

<a :href="item.loc" download>File Template</a>

using the same data return as I said. Using the require statement with the loader puts the "required" files into the wwwroot/files folder when the project builds. Thanks again, OverCoder, this saved me a lot of time.

Prasad Kavinda
  • 174
  • 3
  • 15
Judd
  • 409
  • 1
  • 3
  • 13
  • This is a bit obscure. What require statement? What is the exact folder structure it can see? The project I am working on is already quite sizeable and I am not sure I can just add any `assets` folder anywhere I'd like. – MattSom Nov 27 '21 at 11:39
3

Just an extension to the @Judd's answer. If you don't have a webpack.config.js, you can use the vue.config.js file. (just create it in the root, if it doesn't exist)

vue.config.js

module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.(csv|xlsx|xls)$/,
          loader: 'file-loader',
          options: {
            name: `files/[name].[ext]`
          }
        }
      ],
     },
  },
};

Prasad Kavinda
  • 174
  • 3
  • 15
1

This works for me;

<a href="../../assets/files/FileTemplate.csv" download>Download</a>

It behaves nicely even in dialogs.

Kwesi Aryee
  • 310
  • 2
  • 15
1

I was on Laravel, and I follow this tuto to get mine working:

  1. create an FileController, add a download method
public function downloadFile($file){
   $path = public_path().'/app/upload-folder/'.$file; // or storage_path() if needed
   $header = [
       'Content-Type' => 'application/*',
   ];
   return response()->download($path, $file, $header);
}

  1. create an api entry point in api.php
Route::get('download/upload-folder/{file}', 'FileController@downloadFile');
  1. create a method which uses axios
async downloadTemplateFile(file){
    axios.get('/download/template/file/'+file, {responseType: 'arraybuffer'}).then(res=>{
      let blob = new Blob([res.data], {type:'application/*'})
      let link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = file
      link._target = 'blank'
      link.click();
    })
  }
  1. call from vue template
<li>Download the CSV template <a href="#" @click="downloadTemplateFile('FileTemplate.csv')">here</a></li>

Hope this will helps others ;)

4givN
  • 2,936
  • 2
  • 22
  • 51
1

Place the file you want to download in the public folder as it is the root folder of your application. File Structure Image -> Image Link

Give the href link as below :

<a :href="'/files/SampleFile.xlsx'" class="btn btn-primary" download>Sample File</a>

You can provide any file in the folder structure. For example : .pdf, .xlsx, .png etc

Please note, give the href as :href with file path as " 'your file path' "

Tested and Working on Vue3

hshob_19
  • 11
  • 3
0

Try this:

<a href="../../assets/files/FileTemplate.csv">Download</a>
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Sakkeer A
  • 1,060
  • 1
  • 16
  • 39
0

Try this way and it is with a button:

<a href="/files/Template_Upload.csv" download>
    <button class="btn btn-primary">Download</button>
</a>
W Kenny
  • 1,855
  • 22
  • 33