Bagaimana cara mengekspor info array JavaScript ke csv (di sisi klien)?

514

Saya tahu ada banyak pertanyaan seperti ini tetapi saya perlu melakukan ini menggunakan JavaScript. Saya menggunakan Dojo 1.8dan memiliki semua info atribut dalam array, yang terlihat seperti ini:

[["name1", "city_name1", ...]["name2", "city_name2", ...]]

Adakah ide bagaimana saya dapat mengekspor ini ke CSVsisi klien?

Sam007
sumber

Jawaban:

838

Anda dapat melakukan ini dalam JavaScript asli. Anda harus mem-parsing data Anda ke dalam format CSV yang benar (dengan asumsi Anda menggunakan array array untuk data Anda seperti yang telah Anda jelaskan dalam pertanyaan):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8,";

rows.forEach(function(rowArray) {
    let row = rowArray.join(",");
    csvContent += row + "\r\n";
});

atau cara yang lebih pendek (menggunakan fungsi panah ):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8," 
    + rows.map(e => e.join(",")).join("\n");

Kemudian Anda dapat menggunakan JavaScript window.opendan encodeURIfungsinya untuk mengunduh file CSV seperti:

var encodedUri = encodeURI(csvContent);
window.open(encodedUri);

Edit:

Jika Anda ingin memberikan nama spesifik pada file Anda, Anda harus melakukan hal-hal sedikit berbeda karena ini tidak didukung mengakses data URI menggunakan window.openmetode ini. Untuk mencapai ini, Anda dapat membuat <a>simpul DOM tersembunyi dan mengatur downloadatributnya sebagai berikut:

var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for FF

link.click(); // This will download the data file named "my_data.csv".
Default
sumber
4
Dari yang saya tahu, tidak ada cara untuk melakukan itu menggunakan window.open. Namun, Anda dapat membuat tautan tersembunyi yang memiliki downloadatribut yang disetel ke nama file yang Anda inginkan. Kemudian "mengklik" tautan ini akan mengunduh file dengan nama yang Anda inginkan, saya akan menambahkannya ke jawaban saya.
Default
14
Saya harus menambahkan document.body.appendChild(link);untuk mendapatkan dukungan penuh dalam FF.
Hardbyte
9
Jawaban ini salah: itu akan gagal untuk kasus ini data = [["Hello, world"]]. Itu akan menampilkan dua kolom ketika harus menampilkan satu.
aredridel
18
Ini berfungsi dengan baik untuk seperti ~ 7000 baris. Tetapi mulai memberikan kesalahan ini: NETWORK_INVALID_REQUEST . Apakah ada orang lain yang menghadapi masalah ini juga? Apakah ada batas atas data pada encodeURIComponent()fungsi atau sesuatu? Saya menggunakan Chrome sebagai browser.
Abhidemon
13
@Abhidemon Jawabannya adalah Anda harus menggunakan tipe gumpalan untuk sesuatu yang besar maka itu akan berfungsi dengan baik, misalnya: blob = new Blob ([csvContent], {type: "text / csv"}); href = window.URL.createObjectURL (blob); Lebih detail: stackoverflow.com/a/19328891/1854079
mdubez
257

Berdasarkan jawaban di atas saya membuat fungsi ini yang telah saya uji pada IE 11, Chrome 36 dan Firefox 29

function exportToCsv(filename, rows) {
    var processRow = function (row) {
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0)
                result = '"' + result + '"';
            if (j > 0)
                finalVal += ',';
            finalVal += result;
        }
        return finalVal + '\n';
    };

    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }

    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    } else {
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

Misalnya: https://jsfiddle.net/jossef/m3rrLzk0/

Xavier John
sumber
6
Bisa jatuh-kembali ke window.opendalam elsedari link.download !== undefined.
MrYellow
2
Ini adalah kode yang bagus. Adakah kesempatan Anda bersedia melisensikan ini di bawah sesuatu yang lebih liberal daripada standar SO dari CC-BY-SA? Misalnya, CC0, MIT, BSD, Apache, X11. . . meta.stackexchange.com/questions/12527/…
joseph_morris
1
Saya telah menggunakan metode ini untuk mengimplementasikan ekspor Excel di beberapa aplikasi web. Tetapi Chrome 43+ sekarang telah memindahkan atribut DOM ke rantai prototipe. Pengecualian diberikan pada link.style.visibility='hidden'. B / c atribut DOM dibaca hanya. Rincian lebih lanjut dapat ditemukan di pembaruan.html5rocks.com/2015/04/... di bawah bagian "Menulis ke properti hanya-baca dalam mode ketat akan membuat kesalahan"
Blaise
1
Tanggapan ini adalah yang terbaik sejauh ini. Termasuk case dengan karakter khusus dan tanda kurung.
Vladimir Kostov
2
Saya menggunakan bagian unduhan dari jawaban ini, dan itu bekerja dengan baik di Chrome, terima kasih!
Liran H
77

Solusi ini harus bekerja dengan Internet Explorer 10+, Edge, versi lama dan baru dari Chrome, FireFox, Safari, ++

Jawaban yang diterima tidak akan berfungsi dengan IE dan Safari.

// Example data given in question text
var data = [
  ['name1', 'city1', 'some other info'],
  ['name2', 'city2', 'more info']
];

// Building the CSV from the Data two-dimensional array
// Each column is separated by ";" and new line "\n" for next row
var csvContent = '';
data.forEach(function(infoArray, index) {
  dataString = infoArray.join(';');
  csvContent += index < data.length ? dataString + '\n' : dataString;
});

// The download function takes a CSV string, the filename and mimeType as parameters
// Scroll/look down at the bottom of this snippet to see how download is called
var download = function(content, fileName, mimeType) {
  var a = document.createElement('a');
  mimeType = mimeType || 'application/octet-stream';

  if (navigator.msSaveBlob) { // IE10
    navigator.msSaveBlob(new Blob([content], {
      type: mimeType
    }), fileName);
  } else if (URL && 'download' in a) { //html5 A[download]
    a.href = URL.createObjectURL(new Blob([content], {
      type: mimeType
    }));
    a.setAttribute('download', fileName);
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  } else {
    location.href = 'data:application/octet-stream,' + encodeURIComponent(content); // only this mime type is supported
  }
}

download(csvContent, 'dowload.csv', 'text/csv;encoding:utf-8');

Menjalankan cuplikan kode akan mengunduh data tiruan sebagai csv

Kredit ke dandavis https://stackoverflow.com/a/16377813/1350598

Arne H. Bitubekk
sumber
1
(Paling tidak, kode HTML5) berfungsi tanpa setTimeout.
StubbornShowaGuy
@StubbornShowaGuy keren maka saya akan menghapus setTimeout dari kode contoh :)
Arne H. Bitubekk
Bekerja di Chrome, IE, dan Firefox terbaru. Terima kasih!
walla
Satu-satunya solusi browser yang benar-benar lintas di sini. Perhatikan ini berfungsi pada Safari 10.10 dan Safari seluler. Namun, iframebagian tersebut dapat diganti hanya dengan location.href = ...
Dan
2
CATATAN: Ada kesalahan ketik dalam fungsi, sebenarnya URL.createObjectURL(diakhiri dengan URLtidak Url).
Nathan Hinchey
35

Saya datang ke sini mencari sedikit lebih banyak kepatuhan RFC 4180 dan saya gagal menemukan implementasi, jadi saya membuat (mungkin tidak efisien) satu untuk kebutuhan saya sendiri. Saya pikir saya akan membaginya dengan semua orang.

var content = [['1st title', '2nd title', '3rd title', 'another title'], ['a a a', 'bb\nb', 'cc,c', 'dd"d'], ['www', 'xxx', 'yyy', 'zzz']];

var finalVal = '';

for (var i = 0; i < content.length; i++) {
    var value = content[i];

    for (var j = 0; j < value.length; j++) {
        var innerValue =  value[j]===null?'':value[j].toString();
        var result = innerValue.replace(/"/g, '""');
        if (result.search(/("|,|\n)/g) >= 0)
            result = '"' + result + '"';
        if (j > 0)
            finalVal += ',';
        finalVal += result;
    }

    finalVal += '\n';
}

console.log(finalVal);

var download = document.getElementById('download');
download.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(finalVal));
download.setAttribute('download', 'test.csv');

Semoga ini akan membantu seseorang di masa depan. Ini menggabungkan pengkodean CSV bersama dengan kemampuan untuk mengunduh file. Dalam contoh saya di jsfiddle . Anda dapat mengunduh file (dengan asumsi browser HTML 5) atau melihat output di konsol.

MEMPERBARUI:

Chrome sekarang tampaknya telah kehilangan kemampuan untuk menamai file. Saya tidak yakin apa yang terjadi atau bagaimana cara memperbaikinya, tetapi setiap kali saya menggunakan kode ini (termasuk jsfiddle), file yang diunduh sekarang dinamai download.csv.

Uxonith
sumber
Bagus Chris, saya tidak mengujinya dengan data numerik :)
Uxonith
Saya tidak tahu apakah pemeriksaan nol terakhir adalah perilaku yang diharapkan. Null sangat berbeda dari string kosong. Jika ada yang mengimplementasikan ini, saya akan merekomendasikan nilai null khusus (misalnya: '[[NULL]]'). Pengecualian untuk undefined mungkin juga diinginkan, tetapi saya akan merekomendasikan untuk tidak mengganti null dengan string kosong.
Uxonith
Saya sudah menguji dan menemukan bahwa Anda benar. Ini sepertinya berfungsi di Chrome dan Opera. Safari hanya membuka halaman dengan konten. Internet Explorer ... yah itu IE. Untuk situasi saya, saya akan menghasilkan sisi server CSV saya dan melayani seperti itu, sayangnya
Uxonith
33

Solusi dari @Default berfungsi sempurna di Chrome (terima kasih banyak untuk itu!) Tapi saya punya masalah dengan IE.

Inilah solusinya (berfungsi pada IE10):

var csvContent=data; //here we load our csv data 
var blob = new Blob([csvContent],{
    type: "text/csv;charset=utf-8;"
});

navigator.msSaveBlob(blob, "filename.csv")
Dzarek
sumber
23

Di pembaruan Chrome 35, perilaku atribut unduhan berubah.

https://code.google.com/p/chromium/issues/detail?id=373182

untuk mengerjakan ini di chrome, gunakan ini

var pom = document.createElement('a');
var csvContent=csv; //here we load our csv data 
var blob = new Blob([csvContent],{type: 'text/csv;charset=utf-8;'});
var url = URL.createObjectURL(blob);
pom.href = url;
pom.setAttribute('download', 'foo.csv');
pom.click();
Monu
sumber
1
Anda juga dapat memeriksanya: github.com/mholt/PapaParse/issues/175#issuecomment-201308792
Gabriel
Ini adalah jawaban yang benar saat ini, bukan jawaban yang ditandai diterima!
meow
17

Bekerja untuk semua bahasa

        function convertToCsv(fName, rows) {
        var csv = '';
        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            for (var j = 0; j < row.length; j++) {
                var val = row[j] === null ? '' : row[j].toString();
                val = val.replace(/\t/gi, " ");
                if (j > 0)
                    csv += '\t';
                csv += val;
            }
            csv += '\n';
        }

        // for UTF-16
        var cCode, bArr = [];
        bArr.push(255, 254);
        for (var i = 0; i < csv.length; ++i) {
            cCode = csv.charCodeAt(i);
            bArr.push(cCode & 0xff);
            bArr.push(cCode / 256 >>> 0);
        }

        var blob = new Blob([new Uint8Array(bArr)], { type: 'text/csv;charset=UTF-16LE;' });
        if (navigator.msSaveBlob) {
            navigator.msSaveBlob(blob, fName);
        } else {
            var link = document.createElement("a");
            if (link.download !== undefined) {
                var url = window.URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", fName);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                window.URL.revokeObjectURL(url);
            }
        }
    }



    convertToCsv('download.csv', [
        ['Order', 'Language'],
        ['1', 'English'],
        ['2', 'Español'],
        ['3', 'Français'],
        ['4', 'Português'],
        ['5', 'čeština'],
        ['6', 'Slovenščina'],
        ['7', 'Tiếng Việt'],
        ['8', 'Türkçe'],
        ['9', 'Norsk bokmål'],
        ['10', 'Ελληνικά'],
        ['11', 'беларускі'],
        ['12', 'русский'],
        ['13', 'Українська'],
        ['14', 'հայերեն'],
        ['15', 'עִברִית'],
        ['16', 'اردو'],
        ['17', 'नेपाली'],
        ['18', 'हिंदी'],
        ['19', 'ไทย'],
        ['20', 'ქართული'],
        ['21', '中国'],
        ['22', '한국어'],
        ['23', '日本語'],
    ])
Serdar Didan
sumber
Impresif! (+1). Selamat datang di StackOverflow, sobat!
Rann Lifshitz
bisakah Anda membantu saya memahami apa itu blok kode UTF-16 dan apa yang digunakan di sini
Mar1009
Hai, Mar1009. Ini diperlukan untuk beberapa bahasa. Misalnya, alfabet Cyrillic.
Serdar Didan
13

Ini dia :

<!doctype html>  
<html>  
<head></head>  
<body>
<a href='#' onclick='downloadCSV({ filename: "stock-data.csv" });'>Download CSV</a>

<script type="text/javascript">  
    var stockData = [
        {
            Symbol: "AAPL",
            Company: "Apple Inc.",
            Price: "132.54"
        },
        {
            Symbol: "INTC",
            Company: "Intel Corporation",
            Price: "33.45"
        },
        {
            Symbol: "GOOG",
            Company: "Google Inc",
            Price: "554.52"
        },
    ];

    function convertArrayOfObjectsToCSV(args) {
        var result, ctr, keys, columnDelimiter, lineDelimiter, data;

        data = args.data || null;
        if (data == null || !data.length) {
            return null;
        }

        columnDelimiter = args.columnDelimiter || ',';
        lineDelimiter = args.lineDelimiter || '\n';

        keys = Object.keys(data[0]);

        result = '';
        result += keys.join(columnDelimiter);
        result += lineDelimiter;

        data.forEach(function(item) {
            ctr = 0;
            keys.forEach(function(key) {
                if (ctr > 0) result += columnDelimiter;

                result += item[key];
                ctr++;
            });
            result += lineDelimiter;
        });

        return result;
    }

    window.downloadCSV = function(args) {
        var data, filename, link;

        var csv = convertArrayOfObjectsToCSV({
            data: stockData
        });
        if (csv == null) return;

        filename = args.filename || 'export.csv';

        if (!csv.match(/^data:text\/csv/i)) {
            csv = 'data:text/csv;charset=utf-8,' + csv;
        }
        data = encodeURI(csv);

        link = document.createElement('a');
        link.setAttribute('href', data);
        link.setAttribute('download', filename);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
       }
</script>  
</body>  
</html>  
Madhulika Mukherjee
sumber
1
Jawaban yang luar biasa. Saya memilih jawaban ini karena jawaban yang diterima karena alasan tertentu menempatkan semuanya dalam satu kolom. Ini memecah semuanya menjadi kolom terpisah dan JSON seperti dukungan format data sangat berguna.
Hoser
Ini berfungsi ketika tautan pertama kali ditambahkan ke badan dokumen dan kemudian klik disebut. Dan kemudian dihapus dari dom.
Jay Dubal
1
Jawaban yang bagus, satu-satunya kelemahan adalah tidak berfungsi dengan baik ketika data memiliki pembatas kolom "," yaitu Alamat: '10 Infinite loop lane, Room 56 ', perhatikan koma setelah lajur. Saya sarankan Anda menggunakan tautan PapaParse untuk mengonversi data ke CSV, lalu gunakan metode downloadCSV di atas untuk unduhan file Aktual
phil
Ini berfungsi sempurna untuk saya. Hanya punya satu masalah, saya memiliki beberapa angka dalam array seperti '000002342' tetapi ketika diekspor ke csv, nol terkemuka akan dihapus. Apakah ada cara untuk mencegah hal ini?
Aakarsh Dhawan
13

Orang-orang mencoba untuk membuat string csv mereka sendiri, yang gagal pada kasus tepi, misalnya karakter khusus dan semacamnya, tentu ini adalah masalah yang diselesaikan benar?

papaparse - gunakan untuk pengkodean JSON ke CSV.Papa.unparse().

import Papa from "papaparse";

const downloadCSV = (args) => {  

  let filename = args.filename || 'export.csv';
  let columns = args.columns || null;

  let csv = Papa.unparse({ data: args.data, fields: columns})
  if (csv == null) return;

  var blob = new Blob([csv]);
  if (window.navigator.msSaveOrOpenBlob)  // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
      window.navigator.msSaveBlob(blob, args.filename);
  else
  {
      var a = window.document.createElement("a");
      a.href = window.URL.createObjectURL(blob, {type: "text/plain"});
      a.download = filename;
      document.body.appendChild(a);
      a.click();  // IE: "Access is denied"; see: https://connect.microsoft.com/IE/feedback/details/797361/ie-10-treats-blob-url-as-cross-origin-and-denies-access
      document.body.removeChild(a);
  }

}

Contoh penggunaan

downloadCSV({ 
  filename: 'filename.csv',
  data: [{'a': '1', 'b': 2'}],
  columns: ['a','b']
});

https://github.com/mholt/PapaParse/issues/175 - Lihat komentar ini untuk diskusi dukungan browser.

Glen Thompson
sumber
10

Anda dapat menggunakan potongan kode di bawah ini untuk mengekspor larik ke file CSV menggunakan Javascript.

Ini menangani bagian karakter khusus juga

var arrayContent = [["Séjour 1, é,í,ú,ü,ű"],["Séjour 2, é,í,ú,ü,ű"]];
var csvContent = arrayContent.join("\n");
var link = window.document.createElement("a");
link.setAttribute("href", "data:text/csv;charset=utf-8,%EF%BB%BF" + encodeURI(csvContent));
link.setAttribute("download", "upload_data.csv");
link.click(); 

Berikut ini tautan ke jsfiddle yang berfungsi

Vignesh Subramanian
sumber
1
Jawaban terbaik untuk karakter khusus
Alejandro
# (hashtag) tidak berfungsi!
Nakres
tidak berfungsi di Internet Explorer
Danial
7
//It work in Chrome and IE ... I reviewed and readed a lot of answer. then i used it and tested in both ... 

var link = document.createElement("a");

if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var blob = new Blob([CSV], { type: 'text/csv;charset=utf-8;' });
    var url = URL.createObjectURL(blob);            
    link.setAttribute("href", url);
    link.setAttribute("download", fileName);
    link.style = "visibility:hidden";
}

if (navigator.msSaveBlob) { // IE 10+
   link.addEventListener("click", function (event) {
     var blob = new Blob([CSV], {
       "type": "text/csv;charset=utf-8;"
     });
   navigator.msSaveBlob(blob, fileName);
  }, false);
}

document.body.appendChild(link);
link.click();
document.body.removeChild(link);

//Regards
Mauri
sumber
6

Buat gumpalan dengan data csv. Yaitu var blob = new Blob([data], type:"text/csv");

Jika browser mendukung penghematan yaitu gumpalan if window.navigator.mSaveOrOpenBlob)===true , maka simpan data csv menggunakan: window.navigator.msSaveBlob(blob, 'filename.csv')

Jika browser tidak mendukung penyimpanan dan pembukaan blob, maka simpan data csv sebagai:

var downloadLink = document.createElement('<a></a>');
downloadLink.attr('href', window.URL.createObjectURL(blob));
downloadLink.attr('download', filename);
downloadLink.attr('target', '_blank');
document.body.append(downloadLink);

Cuplikan Kode Lengkap:

var filename = 'data_'+(new Date()).getTime()+'.csv';
var charset = "utf-8";
var blob = new Blob([data], {
     type: "text/csv;charset="+ charset + ";"
});
if (window.navigator.msSaveOrOpenBlob) {
     window.navigator.msSaveBlob(blob, filename);
} else {
    var downloadLink = document.element('<a></a>');
    downloadLink.attr('href', window.URL.createObjectURL(blob));
    downloadLink.attr('download', filename);
    downloadLink.attr('target', '_blank');  
    document.body.append(downloadLink); 
    downloadLink[0].click(); 
}
Liyosi
sumber
5

Ada dua pertanyaan di sini:

  1. Cara mengonversi array menjadi string csv
  2. Cara menyimpan string itu ke file

Semua jawaban untuk pertanyaan pertama (kecuali yang oleh Milimetri) di sini sepertinya berlebihan. Dan yang oleh Milimetri tidak mencakup persyaratan altrenatif, seperti string di sekelilingnya dengan tanda kutip atau mengubah susunan objek.

Inilah pendapat saya tentang ini:

Untuk csv sederhana satu peta () dan gabungan () sudah cukup:

    var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];
    var csv = test_array.map(function(d){
        return d.join();
    }).join('\n');

    /* Results in 
    name1,2,3
    name2,4,5
    name3,6,7
    name4,8,9
    name5,10,11

Metode ini juga memungkinkan Anda untuk menentukan pemisah kolom selain koma di gabungan dalam. misalnya tab:d.join('\t')

Di sisi lain, jika Anda ingin melakukannya dengan benar dan menyertakan string dalam tanda kutip "", maka Anda dapat menggunakan beberapa sihir JSON:

var csv = test_array.map(function(d){
       return JSON.stringify(d);
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, ''); // remove opening [ and closing ]
                                   // brackets from each line 

/* would produce
"name1",2,3
"name2",4,5
"name3",6,7
"name4",8,9
"name5",10,11

jika Anda memiliki berbagai objek seperti:

var data = [
  {"title": "Book title 1", "author": "Name1 Surname1"},
  {"title": "Book title 2", "author": "Name2 Surname2"},
  {"title": "Book title 3", "author": "Name3 Surname3"},
  {"title": "Book title 4", "author": "Name4 Surname4"}
];

// use
var csv = data.map(function(d){
        return JSON.stringify(Object.values(d));
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, '');
Konstantin
sumber
Jika saya tidak salah saya percaya .replaceharus menentukan kurung keriting vs kuadrat.
aaronbartell
.replacedilakukan pada string yang dikembalikan oleh values()yang mengambil objek dan mengembalikan array nilai
Konstantin
The values()Metode tidak ditemukan ketika saya mencoba kode Anda.
aaronbartell
Terima kasih! Di Chrome berfungsi tanpa memanggil values()secara eksplisit Object. Saya mengoreksi contohnya.
Konstantin
5

Banyak solusi roll-your-own di sini untuk mengkonversi data ke CSV, tetapi hampir semua dari mereka akan memiliki berbagai peringatan dalam hal jenis data yang akan mereka format dengan benar tanpa tersandung Excel atau sejenisnya.

Mengapa tidak menggunakan sesuatu yang sudah terbukti: Papa Parse

Papa.unparse(data[, config])

Kemudian gabungkan saja ini dengan salah satu solusi unduhan lokal di sini mis. yang oleh @ArneHB terlihat bagus.

John Rix
sumber
4

Satu fungsi panah dengan ES6:

const dataToCsvURI = (data) => encodeURI(
`data:text/csv;charset=utf-8,${data.map((row, index) =>  row.join(',')).join(`\n`)}`
);

Kemudian :

window.open(
  dataToCsvURI(
   [["name1", "city_name1"/*, ...*/], ["name2", "city_name2"/*, ...*/]]
  )
);

Jika ada yang membutuhkan ini , react-csvapakah ada untuk itu

Abdennour TOUMI
sumber
3
The react-csvperpustakaan bekerja seperti pesona. Solusi hebat bagi siapa saja yang menggunakan modul.
Matt Parrilla
Ini gagal untuk mengamati kasus di mana ada bidang di dalam file CSV dengan koma di dalamnya.
unpollito
2

Inilah cara saya mengunduh file CSV di sisi klien dalam aplikasi Java GWT saya. Terima kasih khusus kepada Xavier John atas solusinya. Sudah diverifikasi untuk berfungsi di FF 24.6.0, IE 11.0.20, dan Chrome 45.0.2454.99 (64-bit). Saya harap ini sedikit menghemat waktu:

public class ExportFile 
{

    private static final String CRLF = "\r\n";

    public static void exportAsCsv(String filename, List<List<String>> data) 
    {
        StringBuilder sb = new StringBuilder();
        for(List<String> row : data) 
        {
            for(int i=0; i<row.size(); i++)
            {
                if(i>0) sb.append(",");
                sb.append(row.get(i));
            }
            sb.append(CRLF);
        }

        generateCsv(filename, sb.toString());
    }

    private static native void generateCsv(String filename, String text)
    /*-{
        var blob = new Blob([text], { type: 'text/csv;charset=utf-8;' });

        if (navigator.msSaveBlob) // IE 10+
        { 
            navigator.msSaveBlob(blob, filename);
        } 
        else 
        {
            var link = document.createElement("a");
            if (link.download !== undefined) // feature detection
            { 
                // Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", filename);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        }
    }-*/;
}
Justin Stein
sumber
2

Berikut ini adalah solusi js asli.

function export2csv() {
  let data = "";
  const tableData = [];
  const rows = [
    ['111', '222', '333'],
    ['aaa', 'bbb', 'ccc'],
    ['AAA', 'BBB', 'CCC']
  ];
  for (const row of rows) {
    const rowData = [];
    for (const column of row) {
      rowData.push(column);
    }
    tableData.push(rowData.join(","));
  }
  data += tableData.join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  a.setAttribute("download", "data.csv");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
<button onclick="export2csv()">Export array to csv file</button>

dabeng
sumber
bekerja dengan baik untuk saya. Terima kasih!
Srijani Ghosh
1

Berikut adalah versi ramah Angular:

  constructor(private location: Location, private renderer: Renderer2) {}

  download(content, fileName, mimeType) {

    const a = this.renderer.createElement('a');

    mimeType = mimeType || 'application/octet-stream';

    if (navigator.msSaveBlob) {

      navigator.msSaveBlob(new Blob([content], {
        type: mimeType
      }), fileName);
    }
    else if (URL && 'download' in a) {

      const id = GetUniqueID();

      this.renderer.setAttribute(a, 'id', id);
      this.renderer.setAttribute(a, 'href', URL.createObjectURL(new Blob([content], {
        type: mimeType
      })));

      this.renderer.setAttribute(a, 'download', fileName);

      this.renderer.appendChild(document.body, a);

      const anchor = this.renderer.selectRootElement(`#${id}`);

      anchor.click();

      this.renderer.removeChild(document.body, a);
    }
    else {
      this.location.go(`data:application/octet-stream,${encodeURIComponent(content)}`);
    }
  };
Chrillewoodz
sumber
1

Jawaban di atas berfungsi, tetapi perlu diingat bahwa jika Anda membuka dalam format .xls, kolom ~~ mungkin ~~ dipisahkan dengan '\t'alih-alih ',', jawabannya https://stackoverflow.com/a/14966131/6169225 berfungsi dengan baik bagi saya, selama saya menggunakan .join('\t')array bukan .join(',').

Marquistador
sumber
berfungsi dengan baik untuk file .xls, BTW Saya memiliki masalah kecil, ketika teks terlalu panjang dan melebihi ukuran grid, sheet tidak terlihat sangat baik, ada petunjuk untuk menyelesaikannya?
gabrielAnzaldo
1

Saya menggunakan fungsi ini untuk mengkonversi string[][]file ke file csv. Ini mengutip sel, jika mengandung a ", a ,atau spasi putih lainnya (kecuali kosong):

/**
 * Takes an array of arrays and returns a `,` sparated csv file.
 * @param {string[][]} table
 * @returns {string}
 */
function toCSV(table) {
    return table
        .map(function(row) {
            return row
                .map(function(cell) {
                    // We remove blanks and check if the column contains
                    // other whitespace,`,` or `"`.
                    // In that case, we need to quote the column.
                    if (cell.replace(/ /g, '').match(/[\s,"]/)) {
                        return '"' + cell.replace(/"/g, '""') + '"';
                    }
                    return cell;
                })
                .join(',');
        })
        .join('\n'); // or '\r\n' for windows

}

Catatan : tidak berfungsi di Internet Explorer <11 kecuali jika mappolyfilled.

Catatan : Jika sel berisi angka, Anda bisa menambahkan cell=''+cellsebelumnya if (cell.replace...untuk mengonversi angka menjadi string.

Atau Anda dapat menulisnya dalam satu baris menggunakan ES6:

t.map(r=>r.map(c=>c.replace(/ /g, '').match(/[\s,"]/)?'"'+c.replace(/"/g,'""')+'"':c).join(',')).join('\n')
Michael_Scharf
sumber
1

Saya akan merekomendasikan menggunakan perpustakaan seperti PapaParse: https://github.com/mholt/PapaParse

Jawaban yang diterima saat ini memiliki beberapa masalah termasuk:

  • gagal jika data berisi koma
  • gagal jika data berisi linebreak
  • itu (jenis) gagal jika data berisi tanda kutip
Falk Tandetzky
sumber
1

Cukup coba ini, beberapa jawaban di sini tidak menangani data unicode dan data yang memiliki koma misalnya tanggal.

function downloadUnicodeCSV(filename, datasource) {
    var content = '', newLine = '\r\n';
    for (var _i = 0, datasource_1 = datasource; _i < datasource_1.length; _i++) {
        var line = datasource_1[_i];
        var i = 0;
        for (var _a = 0, line_1 = line; _a < line_1.length; _a++) {
            var item = line_1[_a];
            var it = item.replace(/"/g, '""');
            if (it.search(/("|,|\n)/g) >= 0) {
                it = '"' + it + '"';
            }
            content += (i > 0 ? ',' : '') + it;
            ++i;
        }
        content += newLine;
    }
    var link = document.createElement('a');
    link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(content));
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};
imal hasaranga perera
sumber
1

Unduh File CSV

  let csvContent = "data:text/csv;charset=utf-8,";
  rows.forEach(function (rowArray) {
    for (var i = 0, len = rowArray.length; i < len; i++) {
      if (typeof (rowArray[i]) == 'string')
        rowArray[i] = rowArray[i].replace(/<(?:.|\n)*?>/gm, '');
      rowArray[i] = rowArray[i].replace(/,/g, '');
    }

    let row = rowArray.join(",");
    csvContent += row + "\r\n"; // add carriage return
  });
  var encodedUri = encodeURI(csvContent);
  var link = document.createElement("a");
  link.setAttribute("href", encodedUri);
  link.setAttribute("download", "fileName.csv");
  document.body.appendChild(link);
  link.click();
Vik2696
sumber
0

Jika ada yang membutuhkan ini untuk knockout js, itu berfungsi baik dengan dasarnya solusi yang diusulkan:

html:

<a data-bind="attr: {download: filename, href: csvContent}">Download</a>

lihat model:

// for the download link
this.filename = ko.computed(function () {
    return ko.unwrap(this.id) + '.csv';
}, this);
this.csvContent = ko.computed(function () {
    if (!this.csvLink) {
        var data = ko.unwrap(this.data),
            ret = 'data:text/csv;charset=utf-8,';

        ret += data.map(function (row) {
            return row.join(',');
        }).join('\n');

        return encodeURI(ret);
    }
}, this);
Milimetri
sumber
0

Saya menambahkan fungsi Xavier Johns untuk juga menyertakan header bidang jika perlu, menggunakan jQuery. Bit $ .each perlu diubah untuk loop javascript asli

function exportToCsv(filename, rows, headers = false) {
    var processRow = function (row) {
        row = $.map(row, function(value, index) {
            return [value];
        });
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            if(i == 0 && j == 0 && headers == true){
                var ii = 0;
                $.each(rows[i], function( index, value ) {
                    //console.log(index);
                    var fieldName = index === null ? '' : index.toString();
                    //console.log(fieldName);
                    var fieldResult = fieldName.replace(/"/g, '""');
                    //console.log(fieldResult);
                    if (fieldResult.search(/("|,|\n)/g) >= 0){
                        fieldResult = '"' + fieldResult + '"';
                    }
                    //console.log(fieldResult);
                    if (ii > 0){
                        finalVal += ',';
                        finalVal += fieldResult;
                    }else{
                        finalVal += fieldResult;
                    }
                    ii++;
                    //console.log(finalVal);
                });
                finalVal += '\n';
                //console.log('end: '+finalVal);
            }
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0){
                result = '"' + result + '"';
            }
            if (j > 0){
                finalVal += ',';
                finalVal += result;
            }else{
                finalVal += result;
            }
        }
        return finalVal + '\n';
    };
    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }
    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    }else{
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}
Bim
sumber
0

Ini adalah jawaban yang dimodifikasi berdasarkan jawaban yang diterima di mana data akan berasal dari JSON.

            JSON Data Ouptut:
             0 :{emails: "SAMPLE Co., [email protected]"}, 1:{emails: "Another CO. , [email protected]"}


            JS:
            $.getJSON('yourlink_goes_here', { if_you_have_parameters}, function(data) {
            var csvContent = "data:text/csv;charset=utf-8,";
            var dataString = '';
             $.each(data, function(k, v) {
                dataString += v.emails + "\n";
             });

            csvContent += dataString;

            var encodedUri = encodeURI(csvContent);
            var link = document.createElement("a");
            link.setAttribute("href", encodedUri);
            link.setAttribute("download", "your_filename.csv");
            document.body.appendChild(link); // Required for FF

            link.click();
        });
Ronald G
sumber
0

Jika Anda mencari solusi yang sangat cepat, Anda juga dapat memberikan kesempatan ke perpustakaan kecil ini yang akan membuat dan mengunduh file CSV untuk Anda: https://github.com/mbrn/filefy

Penggunaannya sangat sederhana:

import { CsvBuilder } from 'filefy';

var csvBuilder = new CsvBuilder("user_list.csv")
  .setColumns(["name", "surname"])
  .addRow(["Eve", "Holt"])
  .addRows([
    ["Charles", "Morris"],
    ["Tracey", "Ramos"]
  ])
  .exportFile();
Mladen Mitrovic
sumber