Як можна експортувати таблиці в Excel з веб-сторінки [закрито]


97

Як можна експортувати таблиці в Excel з веб-сторінки. Я хочу, щоб експорт містив усі форматування та кольори.


9
Найпростіший спосіб - це, мабуть, експорт HTML-документа, який Excel може відкрити.
Pekka

@Pekka Я спробував це, він втрачає все форматування / css / розмір стовпця тощо
code511788465541441

3
@user, де ти оголошуєш розміри стовпців і таке таке? Я не дуже знайомий з експортом даних у Excel, але вам може знадобитися оголосити їх вбудованими, тобто<td style="background-color: ...
Pekka

@user - тут є щонайменше дві різні проблеми: 1) форматування даних, щоб вони відображалися правильно в Excel, і 2) експорт даних за допомогою Javascript, щоб він встановив тип mime правильно, спонукаючи користувача зберегти файл . Ви намагаєтесь вирішити обидві ці проблеми?
nrabinowitz

10
Чому це вважалося "заснованим на думці"? Це дуже просте технічне питання.
brandizzi

Відповіді:


75

Далеко, найчистіший, найпростіший експорт із таблиць у Excel - це плагін Jquery DataTables Table Tools. Ви отримуєте сітку, яка сортує, фільтрує, упорядковує та розміщує сторінки вашими даними, а за допомогою лише декількох додаткових рядків коду та двох невеликих файлів, ви отримуєте експорт до Excel, PDF, CSV, до буфера обміну та до принтера.

Це весь необхідний код:

  $(document).ready( function () {
    $('#example').dataTable( {
        "sDom": 'T<"clear">lfrtip',
        "oTableTools": {
            "sSwfPath": "/swf/copy_cvs_xls_pdf.swf"
        }
    } );
} );

Отже, швидке розгортання, жодних обмежень у веб-переглядачі, мови на стороні сервера не потрібно, і, головне, дуже ЛЕГКО зрозуміти. Це безпрограшний виграш. Єдине, в чому він має обмеження, - це чітке форматування стовпців.

Якщо форматування та кольори є абсолютними зловмисниками, єдиний на 100% надійний метод крос-браузера, який я знайшов, - це використовувати мову на сервері для обробки належних файлів Excel з вашого коду. Моє рішення щодо вибору - PHPExcel Це єдине, що я знайшов поки що, що позитивно обробляє експорт із форматуванням до СУЧАСНОЇ версії Excel з будь-якого браузера, коли ви не надаєте нічого, крім HTML. Дозвольте мені уточнити, але це, безумовно, не так просто, як перше рішення, а також є трохи зародженим ресурсом. Однак, з позитивного боку, він також може виводити безпосередньо в PDF. Коли ви конфігуруєте це, він просто працює, кожен раз.

ОНОВЛЕННЯ - 15 вересня 2016 року: TableTools було припинено на користь нового плагіна під назвою " кнопки ". Ці інструменти виконують ті самі функції, що і старі розширення TableTools, але їх FAR простіше встановити, і вони використовують завантаження HTML5 для сучасних браузерів, з можливістю повернення до оригінального завантаження Flash для браузерів, які не підтримують стандарт HTML5. Як видно з багатьох коментарів, коли я опублікував цю відповідь у 2011 році, головна слабкість TableTools була усунена. Я все ще не можу рекомендувати DataTables достатньо для обробки великої кількості даних просто для розробника та користувача.


2
DataTables повністю Javascript. Просто елемент TableTools використовує Flash, і це мізерно. Я б ніколи не використовував Flash охоче в будь-якому з моїх продуктів!
bpeterson76

16
Я розумію, і я згоден. Але все ж - як би мізерно - там є .swf об’єкт, і він не може працювати без Flash.
магма

8
Таке чудове рішення, але такий сором йому потрібен Flash.
jnthnclrk

Привіт, чи можете ви показати повний приклад, я занадто нуб, щоб це працювало без прикладу!
NoobTom

1
@PramodGaikwad, ні, Datatables замінить NG-таблицю. Вони фактично мають однаковий функціонал, але Datatables набагато зріліші та мають багато-багато інших функцій. Є спіноф Дані, створений спеціально для Angular: l-lin.github.io/angular-datatables/#/welcome
bpeterson76

42

Давно я виявив, що Excel відкриє HTML-файл із таблицею, якщо ми надішлемо його з типом вмісту Excel. Розглянемо документ вище:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Java Friends</title>
</head>
<body>
  <table style="font-weight: bold">
    <tr style="background-color:red"><td>a</td><td>b</td></tr>
    <tr><td>1</td><td>2</td></tr>
  </table>    
</body>
</html>

Я запустив на неї таку закладку:

javascript:window.open('data:application/vnd.ms-excel,'+document.documentElement.innerHTML);

і насправді я отримав його для завантаження у файлі Excel. Однак я не отримав очікуваного результату - файл був відкритий у OpenOffice.org Writer. У цьому моя проблема: у мене немає Excel у цій машині, тому я не можу спробувати її краще. Крім того, цей трюк працював більш-менш шість років тому зі старими браузерами та антикварною версією MS Office, тому я не можу сказати, чи буде він працювати сьогодні.

У будь-якому випадку, в документі вище я додав кнопку, яка б теоретично завантажувала весь документ як файл Excel:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Java Friends</title>
</head>
<body>
  <table style="font-weight: bold">
    <tr style="background-color:red"><td>a</td><td>b</td></tr>
    <tr><td>1</td><td>2</td></tr>
    <tr>
      <td colspan="2">
        <button onclick="window.open('data:application/vnd.ms-excel,'+document.documentElement.innerHTML);">
            Get as Excel spreadsheet
        </button>
      </td>
    </tr>
  </table>    
</body>
</html>

Збережіть його у файлі та натисніть на кнопку. Я люблю знати , якщо він працював чи ні, тому я прошу Вас прокоментувати навіть сказати , що це не робота.


11
Зробив додавання заміни в кінці: window.open ('data: application / vnd.ms-excel,' + document.getElementById ('table'). ExternalHTML.replace (/ / g, '% 20')) ;
VSP

6
Альтернативний спосіб (рекомендовано): window.open ('data: application / vnd.ms-excel,' + encodeURIComponent (document.getElementById ('table'). ExternalHTML));
VSP

5
Відмінно працює у firefox, загортайте свою таблицю в div та потім телефонуйте за допомогою ідентифікатора, document.getElementById('id').innerHTMLщоб вибірково захопити таблицю, інакше всі ваші речі експортуються до електронної таблиці. Не працює в старому IE, але просто відкриває нове вікно з усіма html-заголовками
Abraham Brookes

1
Це просте рішення працює чудово. Подивіться на це повторне запитання, щоб мати можливість встановити ім’я файлу, а також встановити ім'я робочого аркуша. Однотипний розчин; stackoverflow.com/questions/17126453 / ...
Еспен Schulstad

2
Це більше не працює в Office 365 через більш жорсткі заходи безпеки. Файл Excel повинен бути істинним документом Excel, інакше він відкриє помилку під час відкриття.
Філ

12

Можна використовувати старий формат XML Excel 2003 (до OpenXML) для створення рядка, що містить бажаний XML, а потім на стороні клієнта ви можете використовувати URI даних для відкриття файлу за допомогою типу mime XSL або надіслати файл до клієнта, що використовує міметик Excel "Content-Type: application / vnd.ms-excel" з боку сервера.

  1. Відкрийте Excel та створіть аркуш із потрібним форматуванням та кольорами.
  2. Збережіть робочу книгу Excel як "XML-електронну таблицю 2003 (* .xml)"
  3. Відкрийте отриманий файл у текстовому редакторі, як блокнот, і скопіюйте значення у рядок у вашій програмі
  4. Якщо припустити, що ви використовуєте підхід на стороні клієнта з урі даних, код виглядатиме так:
    
    <script type="text/javascript">
    var worksheet_template = '<?xml version="1.0"?><ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'+
                 '<ss:Styles><ss:Style ss:ID="1"><ss:Font ss:Bold="1"/></ss:Style></ss:Styles><ss:Worksheet ss:Name="Sheet1">'+
                 '<ss:Table>{{ROWS}}</ss:Table></ss:Worksheet></ss:Workbook>';
    var row_template = '<ss:Row ss:StyleID="1"><ss:Cell><ss:Data ss:Type="String">{{name}}</ss:Data></ss:Cell></ss:Row>';
    </script>
    
    
  5. Тоді ви можете використовувати заміну рядків для створення колекції рядків, які потрібно вставити в шаблон робочого аркуша
    
    <script type="text/javascript">
    var rows = document.getElementById("my-table").getElementsByTagName('tr'),
      row_data = '';
    for (var i = 0, length = rows.length; i < length; ++i) {
    row_data += row_template.replace('{{name}}', rows[i].getElementsByTagName('td')[0].innerHTML);
    }
    </script>
    
    
  6. Після того як ви зібрали інформацію, створіть остаточний рядок і відкрийте нове вікно, використовуючи URI даних

    
    <script type="text/javascript">
    var worksheet = worksheet_template.replace('{{ROWS}}', row_data);

    window.open('data:application/vnd.ms-excel,'+worksheet); </script>

Варто зазначити, що старші браузери не підтримують схему URI даних, тому вам може знадобитися створити сторону файлового сервера для тих браузерів, які не підтримують її.

Можливо, вам також знадобиться виконати базове кодування на вмісті URI даних, для чого може знадобитися бібліотека js , а також додати рядок '; base64' після типу mime у URI даних.


Хоча приємно використовувати OpenXML, це рішення не буде працювати над таблицями з colspans або rowspans без великої роботи на генераторі javascript
Eduardo Molteni

1
Дякую, що навчили мене чомусь, а не сказали мені використовувати плагін, високо оцінений. Варто зазначити, що цей підхід і сьогодні добре працює.
Бенджамін Груенбаум

Цікаво, спробував такий підхід. Я просто отримую всю <? Xml version = "1.0"?> <Ss: Workbook xmlns: ss = "urn: schemas-microsoft-com: office: електронна таблиця"> '+' <ss: Styles> <ss: Style ss : ID = "1"> <ss: Шрифт ss: Bold = "1" /> </ ss: Стиль> </ ss: Стилі> <ss: Лист ss: Name = "Sheet1"> '+' <ss: Таблиця> значення з моїми рядками, записаними в одну клітинку, включаючи всі рядки в одну клітинку Що я пропускаю?
CromeX

6

У Excel є маловідома функція під назвою "Веб-запити", яка дозволяє отримувати дані майже з кожної веб-сторінки без додаткового програмування.

Веб-запит запускає HTTP-запит безпосередньо з Excel і копіює частину або всі отримані дані (і необов'язково форматування) на робочий аркуш.

Визначивши веб-запит, ви можете оновити його в будь-який час, навіть не залишаючи excel. Таким чином, вам не потрібно насправді "експортувати" дані та зберігати їх у файл - ви краще оновіть дані так само, як із бази даних.

Ви навіть можете скористатися параметрами URL-адреси, довідавшись, що вам підкажуть певні критерії фільтра тощо.

Однак мінуси, які я помітив поки що:

  • динамічно завантажені дані недоступні, оскільки Javascript не виконується
  • Довжина URL-адреси обмежена

Ось питання про те, як створити веб-запити в Excel. Він посилається на веб-сайт довідки Microsoft про те, як отримати зовнішні дані з веб-сторінки


Це не спрацює, якщо URL також знаходиться за стіною входу.
Акшар

Це працює з базовим, а також аутентифікацією на основі форми, але з останнім вам, можливо, доведеться натиснути "редагувати запит", щоб знову ввести облікові дані та отримати новий файл cookie час
HAL 9000,

5

Це php, але ви, можливо, зможете змінити його на javascript:

<?php>
$colgroup = str_repeat("<col width=86>",5);
$data = "";
$time = date("M d, y g:ia");
$excel = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns=\"http://www.w3.org/TR/REC-html40\">
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html>
<head>
<meta http-equiv=\"Content-type\" content=\"text/html;charset=utf-8\" />
<style id=\"Classeur1_16681_Styles\">
.xl4566 {
color: red;
}
</style>
</head>
<body>
<div id=\"Classeur1_16681\" align=center x:publishsource=\"Excel\">
<table x:str border=0 cellpadding=0 cellspacing=0 style=\"border-collapse: collapse\">
<colgroup>$colgroup</colgroup>
<tr><td class=xl2216681><b>Col1</b></td><td class=xl2216681><b>Col2</b></td><td class=xl2216681 ><b>Col3</b></td><td class=xl2216681 ><b>Col4</b></td><td class=xl2216681 ><b>Col5</b></td></tr>
<tr><td class=xl4566>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
</table>
</div>
</body>
</html>";
  $fname = "Export".time().".xls";
  $file = fopen($fname,"w+");
  fwrite($file,$excel);
  fclose($file);
  header('Content-Type: application/vnd.ms-excel');
  header('Content-Disposition: attachment; filename="'.basename($fname).'"');
  readfile($fname);
  unlink($fname); ?>    

5

По-перше, я б не рекомендував спробувати експортувати Html і сподіваюся, що екземпляр Excel користувача підбере його. Мій досвід того, що це рішення загрожує проблемами, включаючи несумісність з клієнтами Macintosh і помилкою користувача, що файл, про який йде мова, не вказаного формату. Найбільш захищене від користувачів рішення, яке стосується користувачів, - це серверне рішення, на якому ви використовуєте бібліотеку для створення фактичного файлу Excel і відправляєте його назад користувачеві. Наступним найкращим рішенням і універсальнішим рішенням буде використання формату Open XML. Я зіткнувся з декількома рідкісними проблемами сумісності зі старими версіями Excel, але в цілому це повинно дати вам рішення, яке буде працювати на будь-якій версії Excel, включаючи Macs.

Відкрийте XML


4

Мозілла все ще підтримує базу 64 URI. Це дозволяє динамічно складати двійковий вміст за допомогою javascript:

<a href="data:application/vnd.ms-excel<base64 encoded binary excel content here>"> download xls</a>

якщо ваш файл excel не дуже фантазійний (немає діаграм, формул, макрозів), ви можете перекопатись у формат і скласти байти для свого файлу, а потім закодувати їх з base64 і помістити в href

зверніться до https://developer.mozilla.org/en/data_URIs


2

Це насправді простіше, ніж ви могли б подумати: "Просто" скопіюйте таблицю HTML (тобто HTML-код таблиці) в буфер обміну. Excel знає, як розшифрувати HTML-таблиці; він навіть спробує зберегти атрибути.

Важкою частиною є "копіювання таблиці у буфер обміну", оскільки немає стандартного способу доступу до буфера обміну з JavaScript. Дивіться цю публікацію в блозі: Доступ до буфера обміну системи з JavaScript - Святий Грааль?

Тепер все, що вам потрібно, - це таблиця як HTML. Я пропоную jQuery та метод html () .


2

Цей код є лише IE, тому він корисний лише в ситуаціях, коли ви знаєте, що всі ваші користувачі будуть використовувати IE (як, наприклад, у деяких корпоративних середовищах).

<script Language="javascript">
function ExportHTMLTableToExcel()
{
   var thisTable = document.getElementById("tbl").innerHTML;
   window.clipboardData.setData("Text", thisTable);
   var objExcel = new ActiveXObject ("Excel.Application");
   objExcel.visible = true;

   var objWorkbook = objExcel.Workbooks.Add;
   var objWorksheet = objWorkbook.Worksheets(1);
   objWorksheet.Paste;
}
</script>

Я спробував за допомогою цього коду, він відкрив таблицю в excel, але не правильний формат виглядає так, що він просто скопіював HTML-код у таблиці. ось так: <TD class = "" bgColor = # ed9fff> SARTIN, DAN </TD> <TD class = "" bgColor = # ed9fff> BALAEZ, BARBARA </TD> Будь-які пропозиції?
Фахад

Це тому, що він використовував InternalHTML. Елемент, який він отримує, IS це таблиця, тому він повинен бути зовнішнім HTML. Я зробив правки
користувач1566694

Я отримую помилку: "Сервер автоматизації не може створити об'єкт" під час створення ActiveXObject. Як я можу це виправити?
Nk SP

2

Припущення:

  1. вказана URL-адреса

  2. перетворення має бути здійснено на стороні клієнта

  3. Системи: Windows, Mac та Linux

Рішення для Windows:

код python, який відкриває вікно ie і має доступ до нього: змінна theurl містить URL ('http: //')

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate(theurl)

Примітка: якщо сторінка не доступна безпосередньо, але для входу в систему, вам потрібно буде це обробити, ввівши дані форми та емулюючи дії користувача з python

ось приклад

from win32com.client import Dispatch
ie.Document.all('username').value=usr
ie.Document.all('password').value=psw

таким же чином для отримання даних з веб-сторінки. Скажімо, елемент з id 'el1' містить дані. отримати текст елемента до змінної

el1 = ie.Document.all('el1').value

тоді, коли дані знаходяться в змінній python, ви можете відкрити екран excel аналогічним чином, використовуючи python:

from win32com.client import Dispatch
xlApp = Dispatch("Excel.Application")
xlWb = xlApp.Workbooks.Open("Read.xls")
xlSht = xlWb.WorkSheets(1)
xlSht.Cells(row, col).Value = el1

Рішення для Mac:

лише порада: використовуйте AppleScript - у нього є простий та подібний API, як win32com.client Dispatch

Рішення для Linux:

java.awt.Robot може працювати для цього, він має клацання, натискання клавіш (можна використовувати гарячі клавіші), але жоден API для Linux, про який я знаю, може працювати так просто, як AppleScript


1

простий пошук у Google виявив це:

Якщо дані насправді є HTML-сторінкою і НЕ були створені ASP, PHP чи іншою мовою сценаріїв, і ви використовуєте Internet Explorer 6, а на комп'ютері встановлений Excel, просто клацніть правою кнопкою миші на сторінці та подивіться через меню. Ви повинні побачити "Експорт у Microsoft Excel." Якщо всі ці умови вірні, натисніть на пункт меню і через кілька підказок він буде імпортований у Excel.

якщо ви не можете цього зробити, він дає альтернативний метод перетягування:

http://www.mrkent.com/tools/converter/



0

Є два практичні способи зробити це автоматично, тоді як лише одне рішення можна використовувати в усіх браузерах. Перш за все, ви повинні використовувати відкриту специфікацію xml для створення листа excel. Доступні безкоштовні додатки від Microsoft, які роблять цей формат доступним і для старих офісних версій. Відкритий xml є стандартним з офісу 2007 року. Два способи очевидні як сервер, так і клієнт.

Реалізація клієнта використовує новий стандарт CSS, який дозволяє зберігати дані, а не лише URL-адресу. Це чудовий підхід, тому що вам не потрібен будь-який серверний дзвінок, лише дані та трохи JavaScript. Недоліком вбивства є те, що Microsoft не підтримує всі його частини в нинішніх версіях IE (я не знаю про IE9). Microsoft обмежує дані для зображення, але нам потрібен документ. У Firefox це працює чудово. Для мене ІЕ був точкою вбивства.

Інший спосіб - користуватися реалізацією на сервері. Має бути багато реалізацій відкритого XML для всіх мов. Вам потрібно просто схопити один. У більшості випадків це буде найпростіший спосіб змінити Viewmodel, щоб отримати документ, але, безумовно, ви можете відправити всі дані з Clientside назад на сервер і зробити те ж саме.


Чи може проголосувати нижчий виборець прокоментувати, що є причиною відмови?
sra

0
   function normalexport() {

       try {
           var i;
           var j;
           var mycell;
           var tableID = "tblInnerHTML";
           var drop = document.getElementById('<%= ddl_sections.ClientID %>');
           var objXL = new ActiveXObject("Excel.Application");
           var objWB = objXL.Workbooks.Add();
           var objWS = objWB.ActiveSheet;
           var str = filterNum(drop.options[drop.selectedIndex].text);
           objWB.worksheets("Sheet1").activate; //activate dirst worksheet
           var XlSheet = objWB.activeSheet; //activate sheet
           XlSheet.Name = str; //rename


           for (i = 0; i < document.getElementById("ctl00_ContentPlaceHolder1_1").rows.length - 1; i++) {
               for (j = 0; j < document.getElementById("ctl00_ContentPlaceHolder1_1").rows(i).cells.length; j++) {
                   mycell = document.getElementById("ctl00_ContentPlaceHolder1_1").rows(i).cells(j);

                   objWS.Cells(i + 1, j + 1).Value = mycell.innerText;

                   //                                                objWS.Cells(i + 1, j + 1).style.backgroundColor = mycell.style.backgroundColor;
               }
           }

           objWS.Range("A1", "L1").Font.Bold = true;
           //                objWS.Range("A1", "L1").Font.ColorIndex = 2;
           //                 objWS.Range("A1", "Z1").Interior.ColorIndex = 47;

           objWS.Range("A1", "Z1").EntireColumn.AutoFit();

           //objWS.Range("C1", "C1").ColumnWidth = 50;

           objXL.Visible = true;

       } catch (err) {
           alert("Error. Scripting for ActiveX might be disabled")
           return
       }
       idTmr = window.setInterval("Cleanup();", 1);

   }


   function filterNum(str) {

       return str.replace(/[ / ]/g, '');
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.