Експорт у CSV за допомогою jQuery та html


76

У мене є табличні дані, які мені потрібно експортувати до csv без використання будь-якого зовнішнього плагіна чи API. Я використовував window.openметод передачі типів mime, але стикався з проблемами, як показано нижче:

Як визначити, чи встановлено в системі Microsoft Excel або Open Office за допомогою jquery

Код повинен бути незалежним від того, що те, що встановлюється в системі, тобто openoffice або ms excel. Я вважаю, що CSV - це формат, який можна очікувати в обох редакторах.

КОД

    <html>

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>  

<script type="text/JavaScript">
$(document).ready(function(){
    $("#btnExport").click(function(e) {
        var msg = GetMimeTypes();
        //OpenOffice
        window.open('data:application/vnd.oasis.opendocument.spreadsheet,' + $('#dvData').html());
        //MS-Excel
        window.open('data:application/vnd.ms-excel,' + $('#dvData').html());
        //CSV
        window.open('data:application/csv,charset=utf-8,' + $('#dvData').html());
        e.preventDefault();
    });
});

function GetMimeTypes () {
    var message = "";
        // Internet Explorer supports the mimeTypes collection, but it is always empty
    if (navigator.mimeTypes && navigator.mimeTypes.length > 0) {
        var mimes = navigator.mimeTypes;
        for (var i=0; i < mimes.length; i++) {
            message += "<b>" + mimes[i].type + "</b> : " + mimes[i].description + "<br />";
        }
    }
    else {
        message = "Your browser does not support this ";
       //sorry!
    }

    return ( message);
}
</script>

</head>
<body>
<div id="dvData">
<table>
    <tr>
        <th>Column One </th>
        <th>Column Two</th>
        <th>Column Three</th>
    </tr>
    <tr>
        <td>row1 Col1</td>
        <td>row1 Col2</td>
        <td>row1 Col3</td>
   </tr>
   <tr>
        <td>row2 Col1</td>
        <td>row2 Col2</td>
        <td>row2 Col3</td>
   </tr>
      <tr>
        <td>row3 Col1</td>
        <td>row3 Col2</td>
        <td>row3 Col3</td>  
   </tr>
</table>
</div>
<br/>
<input type="button" id="btnExport" value=" Export Table data into Excel " />

</body>

Помилки:

CSV: не розпізнано в браузерах

ODS і Excel: працює, але я не можу знайти, який з них створити, коли в системі встановлено Excel або встановлено openoffice?

Версія IE 8: вона повністю не працює, відкривається в новому вікні та, як показано на скріншоті нижче.

введіть тут опис зображення


З якою проблемою ви точно стикаєтесь? Я не розумію.
Pekka

я не можу експортувати його в CSV за допомогою jquery та html ... я не хочу використовувати для нього жоден плагін .. я використовував тип mime, але, здається, це не працює
GOK

Потім покажіть код і опишіть, що саме не працює як? Які повідомлення про помилки ви отримуєте? І т. Д.
Пекка

@Pekka 웃: Дивіться РЕДАКТУВАТИ, якщо зараз ви також не розумієте, будьте конкретні, щоб запитувати подяки
GOK

Що сталося @Pekka 웃 .... З вашого боку немає рішень ???
ГОК

Відповіді:


127

Демо

Пояснення див. Нижче.

$(document).ready(function() {

  function exportTableToCSV($table, filename) {

    var $rows = $table.find('tr:has(td)'),

      // Temporary delimiter characters unlikely to be typed by keyboard
      // This is to avoid accidentally splitting the actual contents
      tmpColDelim = String.fromCharCode(11), // vertical tab character
      tmpRowDelim = String.fromCharCode(0), // null character

      // actual delimiter characters for CSV format
      colDelim = '","',
      rowDelim = '"\r\n"',

      // Grab text from table into CSV formatted string
      csv = '"' + $rows.map(function(i, row) {
        var $row = $(row),
          $cols = $row.find('td');

        return $cols.map(function(j, col) {
          var $col = $(col),
            text = $col.text();

          return text.replace(/"/g, '""'); // escape double quotes

        }).get().join(tmpColDelim);

      }).get().join(tmpRowDelim)
      .split(tmpRowDelim).join(rowDelim)
      .split(tmpColDelim).join(colDelim) + '"';

    // Deliberate 'false', see comment below
    if (false && window.navigator.msSaveBlob) {

      var blob = new Blob([decodeURIComponent(csv)], {
        type: 'text/csv;charset=utf8'
      });

      // Crashes in IE 10, IE 11 and Microsoft Edge
      // See MS Edge Issue #10396033
      // Hence, the deliberate 'false'
      // This is here just for completeness
      // Remove the 'false' at your own risk
      window.navigator.msSaveBlob(blob, filename);

    } else if (window.Blob && window.URL) {
      // HTML5 Blob        
      var blob = new Blob([csv], {
        type: 'text/csv;charset=utf-8'
      });
      var csvUrl = URL.createObjectURL(blob);

      $(this)
        .attr({
          'download': filename,
          'href': csvUrl
        });
    } else {
      // Data URI
      var csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

      $(this)
        .attr({
          'download': filename,
          'href': csvData,
          'target': '_blank'
        });
    }
  }

  // This must be a hyperlink
  $(".export").on('click', function(event) {
    // CSV
    var args = [$('#dvData>table'), 'export.csv'];

    exportTableToCSV.apply(this, args);

    // If CSV, don't do event.preventDefault() or return false
    // We actually need this to be a typical hyperlink
  });
});
a.export,
a.export:visited {
  display: inline-block;
  text-decoration: none;
  color: #000;
  background-color: #ddd;
  border: 1px solid #ccc;
  padding: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" class="export">Export Table data into Excel</a>
<div id="dvData">
  <table>
    <tr>
      <th>Column One</th>
      <th>Column Two</th>
      <th>Column Three</th>
    </tr>
    <tr>
      <td>row1 Col1</td>
      <td>row1 Col2</td>
      <td>row1 Col3</td>
    </tr>
    <tr>
      <td>row2 Col1</td>
      <td>row2 Col2</td>
      <td>row2 Col3</td>
    </tr>
    <tr>
      <td>row3 Col1</td>
      <td>row3 Col2</td>
      <td>row3 Col3</td>
    </tr>
    <tr>
      <td>row4 'Col1'</td>
      <td>row4 'Col2'</td>
      <td>row4 'Col3'</td>
    </tr>
    <tr>
      <td>row5 &quot;Col1&quot;</td>
      <td>row5 &quot;Col2&quot;</td>
      <td>row5 &quot;Col3&quot;</td>
    </tr>
    <tr>
      <td>row6 "Col1"</td>
      <td>row6 "Col2"</td>
      <td>row6 "Col3"</td>
    </tr>
  </table>
</div>


Станом на 2017 рік

Тепер використовує HTML5 Blobі URLяк переважний метод, Data URIяк запасний варіант.

В Internet Explorer

Інші відповіді пропонують window.navigator.msSaveBlob; проте це відомо IE10 / Window 7 та IE11 / Windows 10 аварійно завершують роботу . Чи працює це за допомогою Microsoft Edge, сумнівно (див. Квиток на випуск Microsoft Edge # 10396033 ).

Просто виклик цього у власних інструментах розробника / консолі Microsoft призводить до аварійного завершення роботи браузера:

navigator.msSaveBlob(new Blob(["hello"], {type: "text/plain"}), "test.txt");


Через чотири роки після моєї першої відповіді нові версії IE включають IE10, IE11 та Edge. Всі вони виходять з ладу на функцію, яку винайшла Microsoft (повільний хлопок).

Додайте navigator.msSaveBlobпідтримку на свій страх і ризик.


Станом на 2013 рік

Зазвичай це виконується за допомогою серверного рішення, але це моя спроба вирішення на стороні клієнта. Просто демпінг HTML як результат Data URIне буде працювати, але це корисний крок. Так:

  1. Перетворіть вміст таблиці у дійсний відформатований рядок CSV. (Це найпростіша частина.)
  2. Примусово завантажте браузер. У window.openFirefox підхід не спрацював, тому я використав <a href="{Data URI here}">.
  3. Призначте ім'я файлу за замовчуванням за допомогою атрибута <a>тегу download, який працює лише у Firefox та Google Chrome. Оскільки це лише атрибут, він витончено погіршується.

Примітки

Сумісність

Тестування браузерів включає:

  • Firefox 20+, Win / Mac ( працює )
  • Google Chrome 26+, Win / Mac ( працює )
  • Safari 6, Mac ( працює , але назва файлу ігнорується)
  • IE 9+ ( не вдається )

Кодування вмісту

CSV експортується правильно, але при імпорті в Excel символ üроздруковується якä . Excel неправильно інтерпретує значення.

Введіть, var csv = '\ufeff';а потім Excel 2013+ правильно інтерпретує значення.

Якщо вам потрібна сумісність з Excel 2007, додайте префікси UTF-8 до кожного значення даних. Дивитися також:


Це працює досить добре за моєю вимогою; just for не займає <th> або заголовок для розглянутої таблиці .. це навмисно ... Що робити, якщо у нас є два заголовки з colspan; ми можемо впоратись із цим ??
ГОК

Ой .. але це будь-який спосіб виправити це ?? Я перевіряю це на IE8
ГЗК

19
Просто коротке зауваження: щоб включити також <th>, замініть 'tr: has (td)' на 'tr: has (td), tr: has (th)' і 'td' трохи нижче на ' td, th '.
Wouter

PS Якщо у кого є якісь - які питання , отримати ім'я файлу для роботи, це пов'язано питання SO має рішення: stackoverflow.com/questions/23816005 / ...
clifgriffin

4
Включіть заголовок таблиці (Реалізація пропозицій @Wouter), як показано нижче, 1) var $ рядки = $ table.find ('tr: має (td), tr: має (th)'), 2) $ cols = $ row.find ( 'td, th');
Бала

7

Я не впевнений, що наведений вище код генерації CSV настільки великий, що, здається, пропускає thкомірки, а також, здається, не допускає коми у цьому значенні. Отже, ось мій код генерації CSV, який може бути корисним.

Він передбачає, що у вас є $tableзмінна, яка є об’єктом jQuery (наприклад, var $table = $('#yourtable');)

$rows = $table.find('tr');

var csvData = "";

for(var i=0;i<$rows.length;i++){
                var $cells = $($rows[i]).children('th,td'); //header or content cells

                for(var y=0;y<$cells.length;y++){
                    if(y>0){
                      csvData += ",";
                    }
                    var txt = ($($cells[y]).text()).toString().trim();
                    if(txt.indexOf(',')>=0 || txt.indexOf('\"')>=0 || txt.indexOf('\n')>=0){
                        txt = "\"" + txt.replace(/\"/g, "\"\"") + "\"";
                    }
                    csvData += txt;
                }
                csvData += '\n';
 }

2
 <a id="export" role='button'>
        Click Here To Download Below Report
    </a>
    <table id="testbed_results" style="table-layout:fixed">
        <thead>
            <tr width="100%" style="color:white" bgcolor="#3195A9" id="tblHeader">
                <th>Name</th>
                <th>Date</th>
                <th>Speed</th>
                <th>Column2</th>
                <th>Interface</th>
                <th>Interface2</th>
                <th>Sub</th>
                <th>COmpany result</th>
                <th>company2</th>
                <th>Gen</th>
            </tr>
        </thead>
        <tbody>
            <tr id="samplerow">
                <td>hello</td>
                <td>100</td>
                <td>200</td>
                <td>300</td>
                <td>html2svc</td>
                <td>ajax</td>
                <td>200</td>
                <td>7</td>
                <td>8</td>
                <td>9</td>
            </tr>
            <tr>
                <td>hello</td>
                <td>100</td>
                <td>200</td>
                <td>300</td>
                <td>html2svc</td>
                <td>ajax</td>
                <td>200</td>
                <td>7</td>
                <td>8</td>
                <td>9</td>
            </tr>
        </tbody>
    </table>

    $(document).ready(function () {
        Html2CSV('testbed_results', 'myfilename','export');
    });



    function Html2CSV(tableId, filename,alinkButtonId) {
        var array = [];
        var headers = [];
        var arrayItem = [];
        var csvData = new Array();
        $('#' + tableId + ' th').each(function (index, item) {
            headers[index] = '"' + $(item).html() + '"';
        });
        csvData.push(headers);
        $('#' + tableId + ' tr').has('td').each(function () {

            $('td', $(this)).each(function (index, item) {
                arrayItem[index] = '"' + $(item).html() + '"';
            });
            array.push(arrayItem);
            csvData.push(arrayItem);
        });




        var fileName = filename + '.csv';
        var buffer = csvData.join("\n");
        var blob = new Blob([buffer], {
            "type": "text/csv;charset=utf8;"
        });
        var link = document.getElementById(alinkButton);

        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            link.setAttribute("href", window.URL.createObjectURL(blob));
            link.setAttribute("download", fileName);
        }
        else if (navigator.msSaveBlob) { // IE 10+
            link.setAttribute("href", "#");
            link.addEventListener("click", function (event) {
                navigator.msSaveBlob(blob, fileName);
            }, false);
        }
        else {
            // it needs to implement server side export
            link.setAttribute("href", "http://www.example.com/export");
        }
    }

</script>

2
Ви повинні додати трохи тексту, чому і як ваш код вирішує проблему
Реено,

2

Крихітне оновлення для відповіді @Terry Young , тобто додайте підтримку IE 10+

if (window.navigator.msSaveOrOpenBlob) {
  // IE 10+
  var blob = new Blob([decodeURIComponent(encodeURI(csvString))], {
    type: 'text/csv;charset=' + document.characterSet
  });
  window.navigator.msSaveBlob(blob, filename);
} else {
  // actual real browsers
  //Data URI
  csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvData);

    $(this).attr({
      'download': filename,
      'href': csvData,
      'target': '_blank'
    });
}

Чи буде це спрацьовувати для IE9 для експорту таблиці html, щоб досягти успіху type: 'data:application/vnd.ms-excel;'? Дякую
Дізера

1

Що робити, якщо ви маєте свої дані у форматі CSV і конвертуєте їх у HTML для відображення на веб-сторінці? Ви можете використовувати плагін http://code.google.com/p/js-tables/ . Перевірте цей приклад http://code.google.com/p/js-tables/wiki/Table Оскільки ви вже використовуєте бібліотеку jQuery, я припустив, що ви можете додавати інші бібліотеки інструментарію javascript.

Якщо дані у форматі CSV, ви повинні мати можливість використовувати загальний тип mime "application / octetstream". Усі 3 типи mime, які ви пробували, залежать від програмного забезпечення, встановленого на комп'ютері клієнта.


1

Наскільки я розумію, у вас є дані в таблиці, і ви хочете створити CSV з цих даних. Однак у вас виникли проблеми зі створенням CSV.

Мої думки полягали б у перегляді та аналізі вмісту таблиці та генеруванні рядка з проаналізованих даних. Ви можете перевірити, як перетворити JSON у формат CSV та зберегти у змінній для прикладу. Ви використовуєте jQuery у своєму прикладі, щоб це не враховувалось як зовнішній плагін. Потім вам просто потрібно подати отриманий рядок, використовуючи window.openта використовуючи, application/octetstreamяк запропоновано.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.