2013-06-15 32 views
26

Sto cercando di utilizzare questo script per salvare una tabella html in un file Excel e funziona correttamente, tuttavia non viene visualizzato con il nome corretto, ma con una stringa casuale. E non riesco a capire perché.HTML da Excel a Excel Javascript

mi chiamano con:

<input type="button" onclick="tableToExcel('tablename', 'name')" value="Export to Excel"> 

codice

var tableToExcel = (function() { 
var uri = 'data:application/vnd.ms-excel;base64,' 
, template = '<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"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>' 
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) } 
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) } 
return function(table, name) { 
if (!table.nodeType) table = document.getElementById(table) 
var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML} 
window.location.href = uri + base64(format(template, ctx)) 
} 
})() 
+0

si passa parametri 'nome' e 'tablename' a 'tableToExcel' ma la funzione non dichiara alcun parametro –

+0

Sapete come risolvere questo problema? My js non è eccezionale: P – Coolcrab

+0

Funziona per me ... –

risposta

47

È possibile utilizzare download attributo supportato da dal navigatore moderno per a elemento di ancoraggio. Prima di modificare il codice HTML con l'aggiunta di un ancoraggio invisibile:

<a id="dlink" style="display:none;"></a> 

<input type="button" onclick="tableToExcel('tablename', 'name', 'myfile.xls')" value="Export to Excel"> 

Si noti inoltre che la chiamata alla funzione tableToExcel ora ha 3 ° parametro - in cui si specifica il nome del file.

Ora utilizzare questo codice modificato della vostra funzione originale:

var tableToExcel = (function() { 
     var uri = 'data:application/vnd.ms-excel;base64,' 
     , template = '<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"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>' 
     , base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) } 
     , format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) } 
     return function (table, name, filename) { 
      if (!table.nodeType) table = document.getElementById(table) 
      var ctx = { worksheet: name || 'Worksheet', table: table.innerHTML } 

      document.getElementById("dlink").href = uri + base64(format(template, ctx)); 
      document.getElementById("dlink").download = filename; 
      document.getElementById("dlink").click(); 

     } 
    })() 

Privacy ultime righe 3 Codice: Invece di assegnare URL a finestra - assegnano al nuovo ancoraggio, quindi utilizzare nuovo attributo download per forza scaricare come il nome del file dato e quindi chiamare il semplice metodo click() dell'ancora.

Provalo.

+2

Impressionante! Il nome funziona, ma ora ricevo questo errore: 'Il file che stai tentando di aprire, 'name.xls', è un formato diverso da quello specificato nell'estensione del file. Verifica che il file non sia danneggiato e provenga da una fonte attendibile prima di aprire il file. – Coolcrab

+2

Questo è normale, avresti dovuto farlo anche prima. Questo sta accadendo perché il file non è un vero Excel, ma piuttosto un XML sotto mentite spoglie. Ma dopo quell'avvertimento il file dovrebbe aprirsi OK comunque. Puoi giocare con l'estensione del file per cercare di eliminare l'avviso (ad esempio cambiarlo in .XML ecc.) –

+1

Ciao, so che questo è un post più vecchio ma ricevo un errore che dice che Object non supporta la proprietà o il metodo 'btoa '. – seroth

2

Le 3 righe di codice sopra non funzionano nel mio caso, ma qui ho trovato quello che ho trovato e spero che possa essere d'aiuto.

function tableToExcel(table, name, filename) { 
 
     let uri = 'data:application/vnd.ms-excel;base64,', 
 
     template = '<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"><title></title><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta http-equiv="content-type" content="text/plain; charset=UTF-8"/></head><body><table>{table}</table></body></html>', 
 
     base64 = function(s) { return window.btoa(decodeURIComponent(encodeURIComponent(s))) },   format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; })} 
 
     
 
     if (!table.nodeType) table = document.getElementById(table) 
 
     var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML} 
 

 
     var link = document.createElement('a'); 
 
     link.download = filename; 
 
     link.href = uri + base64(format(template, ctx)); 
 
     link.click(); 
 
}
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
<style> 
 
table { 
 
    font-family: arial, sans-serif; 
 
    border-collapse: collapse; 
 
    width: 100%; 
 
} 
 

 
td, th { 
 
    border: 1px solid #dddddd; 
 
    text-align: left; 
 
    padding: 8px; 
 
} 
 

 
tr:nth-child(even) { 
 
    background-color: #dddddd; 
 
} 
 
</style> 
 
</head> 
 
<body> 
 
<input 
 
    type="button" 
 
    onclick="tableToExcel('myTable', 'name', 'myfile.xls')" 
 
    value="Export to Excel" 
 
> 
 
<table id="myTable"> 
 
    <tr> 
 
    <th>Company</th> 
 
    <th>Contact</th> 
 
    <th>Country</th> 
 
    </tr> 
 
    <tr> 
 
    <td>Alfreds Futterkiste</td> 
 
    <td>Maria Anders</td> 
 
    <td>Germany</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Centro comercial Moctezuma</td> 
 
    <td>Francisco Chang</td> 
 
    <td>Mexico</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Ernst Handel</td> 
 
    <td>Roland Mendel</td> 
 
    <td>Austria</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Island Trading</td> 
 
    <td>Helen Bennett</td> 
 
    <td>UK</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Laughing Bacchus Winecellars</td> 
 
    <td>Yoshi Tannamuri</td> 
 
    <td>Canada</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Magazzini Alimentari Riuniti</td> 
 
    <td>Giovanni Rovelli</td> 
 
    <td>Italy</td> 
 
    </tr> 
 
</table> 
 

 
</body> 
 
</html>

+0

Lo snippet sembra rotto. – WilomGfx

+0

Snippet ha funzionato bene per me su Chrome – brasofilo

+0

A volte, abbiamo bisogno di codificare UTF-8 per 'window.btoa' per funzionare. Vedi [Impossibile eseguire 'btoa' su 'Finestra': La stringa da codificare contiene caratteri al di fuori dell'intervallo Latin1.] (Https://stackoverflow.com/q/232237/12/1287812) – brasofilo