Экспорт HTML-таблицы с правильным форматом в Javascript

У меня есть таблица и столбец суммы. Я хочу экспортировать таблицу с правильным числовым форматом, потому что, когда я экспортирую свою таблицу, я получаю только 100 вместо 100,00.

Моя таблица выглядит так:

ID    Code    Amount    Time
1      1      100.00    2014-09-22 18:59:25
1      1      100.60    2014-09-22 18:59:25
1      1      100.00    2014-09-22 18:59:25
1      1       12.50    2014-09-22 18:59:25

И результат в Excel выглядит так:

ID    Code    Amount    Time
1      1         100    2014-09-22 18:59:25
1      1      100.60    2014-09-22 18:59:25
1      1         100    2014-09-22 18:59:25
1      1        12.5    2014-09-22 18:59:25

Это мой код:

    <script>
    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();

        }
    })()
    function download(){
        $(document).find('tfoot').remove();
        var name = document.getElementById("name").innerHTML;
        tableToExcel('table2', 'Sheet 1', name+'.xls')
        setTimeout("window.location.reload()",0.0000001);

    }
    var btn = document.getElementById("btn");
    btn.addEventListener("click",download);
    </script>

Есть ли способ добиться этого? Я хочу, чтобы мой файл Excel выглядел точно так же, как данные в моей таблице.


person user3771102    schedule 23.09.2014    source источник


Ответы (2)


Попробуйте с

<td style='mso-number-format:"#,##0.00"'>100.00</td>

в таблице HTML.

См. Скрипку: http://jsfiddle.net/ad3xda1z/1/

Привет

Аксель

person Axel Richter    schedule 23.09.2014
comment
Спасибо @Axel! Работает как шарм :) - person user3771102; 24.09.2014
comment
@Adrian: Нет, потому что IE не поддерживает data: URI, используемые в качестве цели ссылки. Но весь подход устарел, поскольку существуют библиотеки, которые действительно могут создавать Excel форматы файлов (*.xls или *.xlsx). Так что больше не нужно подделывать HTML как schemas-microsoft-com:office:excel XML. - person Axel Richter; 09.05.2019

в самом excel:
по умолчанию он не показывает .00, но вы можете изменить его в параметрах форматирования

так что в конечном итоге есть опция (xml), чтобы указать форматирование ячеек. тогда код форматирования будет выглядеть примерно так 0.00

найдено: HTML в Excel: как можно указать Excel, чтобы столбцы считались числами?
примеры кода форматирования
, чтобы вы могли попробовать добавить style="mso-number-format:0\.00000;" в ячейку

другой вариант - попытаться заставить Excel интерпретировать содержимое ячейки как текст - для этого вы можете попытаться добавить к каждому содержимому ячейки префикс '

У меня есть пример фрагмента стека. соответствующий код:

// deep clone of table
//https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode
var temp_table = document.getElementById('table_XXXX').cloneNode(true);
// get all table cells
var table_cells = temp_table.getElementsByTagName('td');
// console.log("table_cells", table_cells);
// modify all table cells
for (var i = 0; i < table_cells.length; i++) { 
    var cell = table_cells[i];
    // console.log("cell", cell);
    // cell.textContent = "'" + cell.textContent;
    cell.setAttribute("style", "mso-number-format:0\.00000;");
}

console.log("temp_table", temp_table);

var tableToExcel = (function () {
	// var uri = 'data:application/vnd.ms-excel;base64,';
	
	var template = '<html lang="en" xml:lang="en" 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><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="DC.language" content="en"><!--[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>';
	
	// var  base64 = function (s) {
		// return window.btoa(unescape(encodeURIComponent(s)))
	// };
	
	var 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
		}
		// return uri + base64(format(template, ctx));
		return format(template, ctx);
	}
})()


function saveAsFile(link, content, mimetype, filename) {
	// https://developer.mozilla.org/en-US/docs/Web/API/Blob
	// var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
	// var oMyBlob = new Blob(aFileParts, {type: 'text/html'}); // the blob
	
	// https://stackoverflow.com/a/16330385/574981
	var blob = new Blob([content], mimetype);
	var url  = URL.createObjectURL(blob);
	
	console.log("update download link:");
	var a = link;
	a.download    = filename;
	a.href        = url;
	// a.textContent = "Download File";
	console.log("download link:", a);
}

function saveAsFile_handleClick(event){
	console.log("saveAsFile_handleClick");
	// deep clone of table
	//https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode
	var temp_table = document.getElementById('table_XXXX').cloneNode(true);
	// get all table cells
	var table_cells = temp_table.getElementsByTagName('td');
	// console.log("table_cells", table_cells);
	// modify all table cells
	for (var i = 0; i < table_cells.length; i++) { 
		var cell = table_cells[i];
		// console.log("cell", cell);
		// cell.textContent = "'" + cell.textContent;
		cell.setAttribute("style", "mso-number-format:0\.000;");
	}
	console.log("temp_table", temp_table);
	// function saveAsFile(link, content, mimetype, filename);
	saveAsFile(
		this,
		tableToExcel(temp_table, 'Sheet 1'), 
		{type: "application/msexcel"}, 
		"test.xls"
	);
} 

function initSystem(){
	console.groupCollapsed("system init:");
	
	// save output button
	var saveOutputButton = document.getElementById("saveAsFile");
	if (saveOutputButton) {
		console.log("add click event to '#saveAsFile':");
		saveOutputButton.addEventListener('click', saveAsFile_handleClick, false);
	}
	
	console.log("finished.");
	console.groupEnd();
}

/* * pure JS - newer browsers...* */
document.addEventListener('DOMContentLoaded', initSystem, false);
#btn {
  margin: 1em;
}

tr:hover {
  background-color: rgba(255, 200, 0, 0.5);
  
}

td {
  padding: 0 1.5em;
  text-align: right;
}


a, a:link {
	margin:					0px;
	padding:				0px;
	text-decoration:		none;
	color:					inherit;
	cursor:					pointer;
	display:				inline;
}


a:hover {
	background-color:		rgba(255,190,000,0.5);
	/*box-shadow:			x y color [blur] [spread] [inset]*/
	box-shadow:				0px 0px 5px rgba(255,190,0,0.5), 0px 0px 20px rgba(255,190,0,0.5);
}


.button, a.button:link {
	display:				block;
	width:					20em;
	padding:				0.5em;
	margin:					1em;
	border-radius:			1em;
	background-color:		rgba(0, 0, 0, 0.35);
	box-shadow:				0px 0px 10px rgba(0,0,0,0.2), 0px 0px 10px rgba(255,255,255,0.1) inset;
	cursor:					pointer;
	text-align:				center;
}

.button:hover, a.button:link:hover {
	background-color:		rgba(0, 0, 0, 0.36);
	box-shadow:				1px 1px 10px rgba(0,0,0,0.3), 0px 0px 10px rgba(255,255,255,0.1) inset;
}
<div>
	<a class="button" id="saveAsFile" href="#">
		Save Table to Excel File
	</a>
</div>


<div id="tablecontainer">
	<table id="table_XXXX">
		<tbody>
			<tr>
				<th>ID</th>
				<th>Code</th>
				<th>Amount</th>
				<th>Time</th>
			</tr>
			<tr>
				<td>1</td>
				<td>1</td>
				<td>100.00</td>
				<td>2014-09-19 18:59:25</td>
			</tr>
			<tr>
				<td>1</td>
				<td>1</td>
				<td>100.60</td>
				<td>2014-09-20 18:59:25</td>
			</tr>
			<tr>
				<td>1</td>
				<td>1</td>
				<td>200.00</td>
				<td>2014-09-21 18:59:25</td>
			</tr>
			<tr>
				<td>1</td>
				<td>1</td>
				<td>12.50</td>
				<td>2014-09-22 18:59:25</td>
			</tr>
		</tbody>
	</table>
</div>

person Stefan Krüger    schedule 23.09.2014
comment
Но мне нужно было показать .00 сразу после открытия файла. Не я его открою. Это клиент. Как его отформатировать? - person user3771102; 23.09.2014
comment
вы можете попытаться экранировать Amount as Text - для этого вам придется изменить данные таблицы так, чтобы перед текстом находился символ '. но вы больше не можете рассчитывать с этим содержимым ячейки. - person Stefan Krüger; 23.09.2014
comment
Что вы имеете в виду под текстом? В моей базе данных, откуда берутся данные, я изменил его тип на varchar, чтобы он также отображал 2 десятичных знака. - person user3771102; 23.09.2014
comment
Я думаю, вы не можете указать формат для ячеек в этой встроенной HTML-вещи. вы не генерируете настоящий xls-файл - это xls-файл, в который встроен html, поэтому у вас нет всех возможностей для форматирования содержимого. Моя идея заключалась в том, чтобы перебрать содержимое вашей таблицы html и префикс содержимого ячейки с помощью '- поэтому excel будет интерпретировать это содержимое как текст. - person Stefan Krüger; 23.09.2014