Coder Social home page Coder Social logo

vue-json-excel's Introduction

JSON to Excel for VUE 2

Download your JSON data as an Excel file directly from the browser. This component is based on the solution proposed on this thread

Important! Extra prompt in Microsoft Excel

The method implemented in this component uses HTML tables to draw the .xls files, Microsoft Excel no longer recognize HTML as native content so a warning message will be displayed before opening the file. The content will be rendered perfectly but the message can't be avoided.

Getting started

Get the package:

npm install vue-json-excel

Register JsonExcel in your vue app entry point:

import Vue from "vue";
import JsonExcel from "vue-json-excel";

Vue.component("downloadExcel", JsonExcel);

In your template

<download-excel :data="json_data">
  Download Data
  <img src="download_icon.png" />
</download-excel>

Props List

Name Type Description Default
data Array Data to be exported.
fields Object Fields inside the JSON Object that you want to export. If none provided, all properties in the JSON will be exported.
export-fields (exportFields) Object Used to fix the problem with other components that use the variable fields, like vee-validate. exportFields works exactly like fields
type string Mime type [xls, csv] xls
name string File name to export. data.xls
header string/Array Title(s) for the data. Can be a string (one title) or an array of strings (multiple titles).
title(deprecated) string/Array same as header, title is maintained for retro-compatibility purposes but its use is not recommended due to the conflict with the HTML5 title attribute.
footer string/Array Footer(s) for the data. Can be a string (one footer) or an array of strings (multiple footers).
default-value (defaultValue) string Use as fallback when the row has no field values. ''
worksheet string Name of the worksheet tab. 'Sheet1'
fetch Function Callback to fetch data before download, if it's set it runs immediately after mouse pressed and before download process.
IMPORTANT: only works if no data prop is defined.
before-generate Function Callback to call a method right before the generate / fetch data, eg:show loading progress
before-finish Function Callback to call a method right before the download box pops out, eg:hide loading progress
stringifyLongNum Boolean stringify long number and decimal(solve the problem of loss of digital accuracy), default: false
escapeCsv Boolean This escapes CSV values in order to fix some excel problems with number fields. But this will wrap every csv data with =" and ", to avoid that you have to set this prop to false. default: True

Example

import Vue from "vue";
import JsonExcel from "vue-json-excel";

Vue.component("downloadExcel", JsonExcel);

const app = new Vue({
  el: "#app",
  data: {
    json_fields: {
      "Complete name": "name",
      City: "city",
      Telephone: "phone.mobile",
      "Telephone 2": {
        field: "phone.landline",
        callback: (value) => {
          return `Landline Phone - ${value}`;
        },
      },
    },
    json_data: [
      {
        name: "Tony Peña",
        city: "New York",
        country: "United States",
        birthdate: "1978-03-15",
        phone: {
          mobile: "1-541-754-3010",
          landline: "(541) 754-3010",
        },
      },
      {
        name: "Thessaloniki",
        city: "Athens",
        country: "Greece",
        birthdate: "1987-11-23",
        phone: {
          mobile: "+1 855 275 5071",
          landline: "(2741) 2621-244",
        },
      },
    ],
    json_meta: [
      [
        {
          key: "charset",
          value: "utf-8",
        },
      ],
    ],
  },
});

In your HTML call it like

<download-excel
  class="btn btn-default"
  :data="json_data"
  :fields="json_fields"
  worksheet="My Worksheet"
  name="filename.xls"
>
  Download Excel (you can customize this with html code!)
</download-excel>

REQUIRED

  • json_data: Contains the data you want to export.
  • json_fields: You can select what fields to export. Specify nested data and assign labels to the fields. The key is the label, the value is the JSON field. This will export the field data 'as is'. If you need to customize the the exported data you can define a callback function. Thanks to @gucastiliao.
let json_fields = {
  // regular field (exported data 'as is')
  fieldLabel: attributeName, // nested attribute supported
  // callback function for data formatting
  anotherFieldLabel: {
    field: anotherAttributeName, // nested attribute supported
    callback: (value) => {
      return `formatted value ${value}`;
    },
  },
};

json_fields is a object that represents which columns will be exported. If no object is provided, the component will be use the first object in your data array to extract the keys as columns names. Json field example:

:export-fields="{
    'Human friendly name': '_name_field_from_json',
    'user's last name': '_last_name_text'
}"

Export CSV

To export JSON as a CSV file, just add the prop type with a value of "csv":

<download-excel
  class="btn btn-default"
  :data="json_data"
  :fields="json_fields"
  type="csv"
  name="filename.xls"
>
  Download CSV (you can customize this with html code!)
</download-excel>

Multi-line values will appear in a single cell

A single text value in the data that contains newline characters will appear as a single cell in Excel. This avoids the undesired behavior of multi-line values getting split into multiple cells that must be merged before using data filters and pivot tables.

For example:

<template>
  <div>
    <json-excel :data="dataForExcel" />
  </div>
</template>
<script>
  import JsonExcel from "@/components/JsonExcel";

  export default {
    components: {
      JsonExcel,
    },
    data: () => {
      return {
        dataForExcel: [
          { colA: "Hello", colB: "World" },
          {
            colA: "Multi-line",
            /* Multi-line value: */
            colB:
              "This is a long paragraph\nwith multiple lines\nthat should show in a single cell.",
          },
          { colA: "Another", colB: "Regular cell" },
        ],
      };
    },
  };
</script>

Example of Excel showing multi-line cell

Fetch Data on Demand

In case you need to fetch data from the server, you could use the fetch prop that allows you to define a callback function that is executed when your user click the download button. This function has to return a JSON value containing the data to export. A basic use case is:

<template>
  <div id="app">

    <hr>
    <h2>Fetch Example</h2>
    <downloadexcel
      class            = "btn"
      :fetch           = "fetchData"
      :fields          = "json_fields"
      :before-generate = "startDownload"
      :before-finish   = "finishDownload">
      Download Excel
    </downloadexcel>
  </div>
</template>

<script>
import downloadexcel from "vue-json-excel";
import axios from 'axios';

export default {
  name: "App",
  components: {
    downloadexcel,
  },
  data(){
    return {
      json_fields: {
        'Complete name': 'name',
        'Date': 'date',
      },
    }
  }, //data
  methods:{
    async fetchData(){
      const response = await axios.get('https://holidayapi.com/v1/holidays?key=a4b2083b-1577-4acd-9408-6e529996b129&country=US&year=2017&month=09');
      console.log(response);
      return response.data.holidays;
    },
    startDownload(){
        alert('show loading');
    },
    finishDownload(){
        alert('hide loading');
    }
  }
};
</script>

Using callbacks

when using callback functions in the fields description, you have three option to retrieve data:

  • field: 'path.to.nested.property' you can retrieve a specific value using the nested property notation.
    json_fields: {
        'Complete name': 'name',
        'City': 'city',
        'Telephone': 'phone.mobile',
        'Telephone 2' : {
            field: 'phone.landline',
            callback: (value) => {
                return `Landline Phone - ${value}`;
            }
        },
    },
  • field: 'define.nested.object' you can retrieve a nested object too.
    json_fields: {s
        'Complete name': 'name',
        'City': 'city',
        'Telephone': 'phone.mobile',
        'Telephone 2' : {
            field: 'phone',
            callback: (value) => {
                return `Landline Phone - ${value.landline}`;
            }
        },
    },
  • Or get the whole row if field is undefined.
    json_fields: {
        'Complete name': 'name',
        'City': 'city',
        'Telephone': 'phone.mobile',
        'Telephone 2' : {
            callback: (value) => {
                return `Landline Phone - ${value.phone.landline}`;
            }
        },
    },

License

MIT

Status

This project is in an early stage of development. Any contribution is welcome :D

vue-json-excel's People

Contributors

asule90 avatar ey-hoffmbe avatar gonzaloalonsod avatar gusehr avatar gustv000 avatar jecovier avatar jesseweb avatar limkeunhak avatar limkeunhak-nexon avatar ljm42 avatar msonowal avatar nmummau avatar per4merkc avatar praba498 avatar sunjiahui avatar tannerwelsh avatar zhegwood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-json-excel's Issues

TypeError: key.split is not a function

Hi, i have one error
error split

I fixed here:

go to node module>vue-json.excel>JsonExcel.vue

Change Line 146:
let property = keys[label] => let property = keys[label]+""

but the data show undefined on my excel

Sorry for my inglish,

False boolean values are not printed

When a field returns a boolean with the value false, the output is empty.

For the following array: [ { emailVerified: false }, { emailVerified: false }, { emailVerified: true }]
The current output is:

| Email verified |
|                |
|                |
|      TRUE      |

The expected output is:

| Email verified |
|      FALSE     |
|      FALSE     |
|      TRUE      |

Current workaround is using .toString() method.

Export multiple sheet per excel file

Hi,
Is there any way to export multiple sheet page in Excel?

Or is there a possible to stack data one after the other in the same page, with each its field and data?
Like an nested array for field and data will yield exported stacked on top of each other?

Thanks in advance,

Regards,

Julien

The key value relationship is not working correctly

The component fails in excel table, the values are not under the correct title.
I have used the component in 2 page, one of it is working correctly but in the other component, when the file is downloaded, the data fails.

callbacks broken

I am having issues with my field callbacks since 0.2.86. With fields defined like this:

'Desc': 'description',
'DescLen': {
  field: 'description',
    callback: (value) => {
      return value.length;
  }
},

The DescLen field will return [object Promise] in the excel file.

I have tried a few things, but I don't have a good enough grasp on async / await to fix it. If I revert back to 0.2.85 then it works fine.

How to access nested json

How to access nested JSON, I always get undefined result

Example json structure that I was tried to access

json_fields : {
    "people.person.name": "name",
 },
json_data : [
 {
    "people" : {"person": {"name": "Ravael"}}
 },
 {
    "people.person.name": {"person": {"name": "Vue"}}
 }
]

Meta tags is not considered on current master

Hi there!

Thanks for the lib!
It is very useful \o/

The meta tags were introduced on this commit: f9a8790
But this code seems to be absent of the current master source code.

It was intentional?
Do we need to update the documentation?
Can you check this issue?

Thanks in advance.

Extra prompt in Excelsheet

Thanks for the lib!

When I try to open the excel file after downloaded, it always says

"The file format and extension of 'filename.xls" don't match. The file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway?"

I tried it in the origin code from Stackoverflow that you referred and it also shows the same message. Is there a way to get rid of it?

json_data returns value of 'undefined'

Tested with the sample data and the file shows correct headers but row data for each column prints out 'undefined'

name,city,country,birthdate,amount
undefined,undefined,undefined,undefined,undefined

fetch prop is nor working

<download-excel :fetch="exportCompanies"
                        :fields="excelFields"
                        name="organizations.xls">
         Download Excel
        </download-excel>


```Function exportCompanies() is returning proper value still excelfile is not generating.


How to export row with nested array

I have a problem with exporting a nested array attribute. It should be some child rows with others have rowspan beside them.
Any solution ?

enhancement to callbacks

I'd like to request an enhancement to the callback function. Currently you can only pass a single field to the callback, I'd like to give it access to the entire row of data.

This will open up more interesting options. Here is a simple example of how it could be used with the sample data:

'Location': {
  field: '_ALL_',
  callback: (value) => {
    return value.city + ", " + value.country;
  }
},

The change to implement this is very minor, just adding an extra if statement inside the getValue() function,

if (field === "_ALL_")
  value = item;
else if (indexes.length > 1)
  value = this.getValueFromNestedItem(item, indexes);
else
  value = item[field];

What do you think?

Just awesome

Wanted to thank you for this package, installed and worked with almost no configs. Thanks a lot! No issues at all!

Recent version breaks when there is a callback on the fields

You get an error like this, because the key isn't the field label but the object with the field and callback properties

    at VueComponent.getNestedData (JsonExcel.vue?ec10:214)
    at eval (JsonExcel.vue?ec10:177)
    at Array.map (<anonymous>)
    at VueComponent.getProcessedJson (JsonExcel.vue?ec10:171)
    at VueComponent.generate (JsonExcel.vue?ec10:76)
    at invoker (vue.runtime.esm.js?2b0e:2023)
    at HTMLDivElement.fn._withTask.fn._withTask (vue.runtime.esm.js?2b0e:1822)```

json id card number turned into weird format and losing the last charater

so i am exporting data of my registered user and there is id card number which contain 13 number ie.: 6112031505780002 and when i export it, in excel it show 6,11203E+15 and it is on general type of data and when i hover my cells into there, i see it is written as 611203150578000. so i lost the last charater...

how to make all of these number just to be a string without any formating? i find this is quite anoying, and it also turn all other fields that only contain number and into something like this 6,11203E+xx (xx = number) if the fields contains number that more then specific digit, i think after 9 or 10 digit it will turned into that...

how can i just get the plain string data?

support custom data type

once a cell is 4 / 9, I'd like to show 4 / 9, just as text , but it will be parsed as date, showing 2018/4/9,
I suggest to extend the fields paramter to change json value from string to json.
current:

myFields: {
  'Bussiness Text' : 'businessText'
}

suggestion:

myFields: {
  'Bussiness Text' : {'businessText', '\@' }
}

after that, in the JsonExcel.vue, add corresponding style to table cell.

xlsData += '<td style="mso-number-format:\@;">' + item[key] + '</td>'

more style : http://cosicimiento.blogspot.com/2008/11/styling-excel-cells-with-mso-number.html

Error: key.split is not a function

Hi @jecovier

I'm getting this error when I install the 0.2.4 version.
key.split is not a function

I see that the current master is different from the downloaded node_module source.

Can you check the npm published component?

Thanks in advance.

Null values are printed as null

I am wondering why null is interpreted as the string value "null"

jsonData = [
  {
    "Name1":  "John",
    "Name2": null
  },
  {
    "Name1":  "Doo",
    "Name2": null
  }
]

Results in the excel file
unbekannt

I did a workaround but this shouldn't be the final solution right?

    computed: {
      json_data () {
          return this.jsonData.map(e => {
              let tmp = {}
              for (let k in e) {
                  tmp[k] = e[k] === null ? '' : e [k]
              }
              return tmp
          })
      }
    }

customize excel output

hi is there any way to customize excel output? like in my table i have table that being grouped like this

<tbody>
   <tr>
        categories
   </tr>
   <tr>
       <td>Title</td>
       <td>Writer</td>
       <td>Published</td>
       <td>Created_at</td>
   </tr>
</tbody>

is it also posibble in excel to generate style like that?

and also i have hide column feature in my html, so i want if i convert json to excel it also remove json fields that is coresponding to those column that hide, ex: i hide writer column that mean in json the writer fields will be removed from there to so in excel it will just show exactly column that shown in html table

Change name button

Hi!
I have a problem, i need to change the name for button

Could help me, please?
captura de pantalla de 2017-08-28 15-45-31

Computed property fields is already defined as a prop

That's the error I'm getting in the console on load. I can't open the downloaded file in drive or on mac preview either.

json_fields: {
        reference_number: 'String',
        location: 'String',
        amount: 'Number',
        severity: 'String',
        original_part: 'String',
        component: 'String',
        component_manufacturer: 'String',
        smc_replacement: 'String',
      },
      json_data: [],
      json_meta: [[{ "key": "charset", "value": "utf-8"}]]

Those are the settings I'm using, the json_data is later populated.

Can't import

I base on Meteor + Vue Componet.

import JsonExcel from 'vue-json-excel';
 Vue.component('downloadExcel', JsonExcel);

image

Cannot open file xls in Ms. Office windows

Hello,

I try to create downloaded file '.xls' in vue. It works.
But, the file can (only) opened in LibreOffice. If I download file and opened in Ms. Office Excel, it can't open. The message appear seems like "... the extention don't match, corrupt or unsafe ...".

Or is there any configuration that must be set?

Thanks :)

CSV Export Won't Escape Commas

The CSV export feature won't escape commas within the data and thus is pretty badly broken.

Escaping in CSVs works as follows:

  1. If the value contains a comma, newline or double quote, then the String value should be returned enclosed in double quotes.
  2. Any double quote characters in the value should be escaped with another double quote.
  3. If the value does not contain a comma, newline or double quote, then the String value should be returned unchanged.

I have this sorted locally and will generate a PR for the fix momentarily.

encode charset

It is not working when set charset

return new Blob([u8arr], {type: 'text/csv;charset=Shift_JIS'})

error in explorer, var fileName error

There is an error that only happens in explorer.

In the JonExcel.vue the method download has a parameter named fileName but it is used later on as filename (pay atention to the n that is in lowercase) and this provokes an error in explorer

best regards

How I can to get a child value

I have tried the export to excel I do not know why but I am not able to get child baules and if it it is an usie or it just me

2 examples:

if I put the example of your wiki I get the following:

json_meta: [
[{
"key": "charset",
"value": "utf-8"
}]
],
json_fields: {
'Complete name': 'name',
'City': 'city',
'Telephone': 'phone.mobile',
'Telephone 2' : {
field: 'phone.landline',
callback: (value) => {
return Landline Phone - ${value};
}
},
},
json_data: [
{
'name': 'Tony Peña',
'city': 'New York',
'country': 'United States',
'birthdate': '1978-03-15',
'phone': {
'mobile': '1-541-754-3010',
'landline': '(541) 754-3010'
}
},
{
'name': 'Thessaloniki',
'city': 'Athens',
'country': 'Greece',
'birthdate': '1987-11-23',
'phone': {
'mobile': '+1 855 275 5071',
'landline': '(2741) 2621-244'
}
}
]

name city phone.mobile [object Object]
undefined undefined undefined undefined
undefined undefined undefined undefined

if I use this another definition

json_fields: {
'name': 'name',
'city': 'his city',
'phone.mobile': 'mobile',
},

I get:

name his city mobile
Tony Peña New York undefined
Thessaloniki Athens undefined

So the wa it works for me is different to the example. I have to put the name in the json at the left and the label in the right. And I am not able to get a child like phone.mobile

Unexpected token <

When used with Nuxt.js, got 'Unexpected token <'

{ /Users/name/Projects/project/node_modules/vue-json-excel/JsonExcel.vue:1
(function (exports, require, module, __filename, __dirname) { <template>
                                                              ^

SyntaxError: Unexpected token <
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)

Retrieve file -> encode to base64 -> send

Hello there,

Thank you for your amazing work, it's really cool :)
Is there a way to retrieve the xls file without downloading it ?

I would like to retrieve and encode it in base64.

Thank you :)
Best regards,

XLSX support?

Apologies if this has been addressed already first and foremost.

I really like this component that you have made and am wondering if there is an ability to support changing the extension to xlsx in the near future?

ty so much :)

Urgent Help Needed

I did a correct import of the vue-json-excel library and also did:
import JsonExcel from 'vue-json-excel'

component: {
'downloadExcel': JsonExcel
},

But here's the error I get on the console:

Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Unable to bind to footer attribute

Tried binding data to the footer attribute mentioned in the document but it is not processed.

//Vue code of json to excel

<download-excel class="pull-left btn btn-inverse waves-effect waves-light"
:title = "excel.excel_title"
:fields= "excel.excel_fields"
:data = "excel.excel_data"
footer = "Test" 
:name = "excel.filename">
EXCEL
</download-excel>

//data declared

excel:{
excel_data:[],
excel_title:'',
excel_footer:'',
filename:'',
excel_fields:{},
},

I have calculated and seen to i that the data is binded to excel object and then to the json to excel element except for footer(I tried binding initially and later gave the value directly in the element).

Receipt Details(2018-10-17 - 2018-10-17).xls.zip

How to configure with Webpack?

Hi. I'm using Vue with webpack, and I can't configure this to work properly

My main.js is like this:

import Vue from 'vue'
import store from './store/store'
import App from './App'
import router from './router'
import Vuetify from 'vuetify'
import VueJWT from 'vuejs-jwt'
import JsonExcel from 'vue-json-excel'
import 'vuetify/dist/vuetify.min.css'
import 'font-awesome/css/font-awesome.css'
/* eslint-disable */

Vue.config.productionTip = false

Vue.use(Vuetify, {
  theme: {
    primary: '#372924',
    secondary: '#a1947d',
    accent: '#8c9eff',
    error: '#b71c1c',
    white: '#fff'
  }
})

Vue.use(VueJWT, JsonExcel)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

And i'm using the tag in the component I want to generate the Excel file.

What is the correct way to configure this using Vue with webpack like this?

Error utf8 while exporting in .csv

As you can see in the screenshot, i have errors while exporting in .csv my json.
This issue comes out just when I open the .csv with Excel, instead of Notepad++ that format the characters correctly.
I don't know if you can do something on your own about this..
image

Blob is not defined

Why does it appear that the Blob class is not defined?
npm v5.5.0
vuejs v2.3.3

"null" in exported excel file

Hi,

First of all thanks for putting together this work. After a little bit of tinkering, I was able to get it work.
Somehow the excel it generated has "null" in the first row, as in the following screenshot:
image

I assume this is something that can be passed from meta prop, but somehow the following meta didn't make a difference:

json_meta: [ [{ "key": "charset", "value": "utf-8" }], [{ "key": "head", "value": "Raw Data" }] ]

Am I missing anything?

Also on a side note, any chance to add a function to export simple CSV file?

Thanks again.

Add Custom Info Above Data Grid

Good day. Can this component be able to add custom information above the data grid? Like

User: Kosaki Onodera
Age: 17
Gender: Female

Thanks in advance. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.