Наше веб-приложение имеет возможность экспортировать HTML-таблицы в Excel, и это прекрасно работает. Но мы не можем заставить его поддерживать несколько строк в столбцах. Мы испробовали множество решений, в основном с CSS, как описано здесь
но ничего из того, что мы обнаружили, не помогло. Наш поток в основном так:
Мы создаем хэш-таблицу, в которой ключи являются заголовками столбцов, а значения - значениями ячеек. Затем мы создаем HTML-таблицу из хеш-таблицы с помощью Razor, и, наконец, эта HTML-таблица попадает к клиенту, где она преобразуется в шаблон XML, который Excel понимает, и загружается браузером. Вот некоторый код, чтобы попытаться дать вам почувствовать, какой код задействован:
Код бритвы (состоит из страницы и компонента):
Страница:
@using System.Text
@using System.Text.Encodings.Web
@using Mchp.DigitalRural.Services.ViewModel
@model DataToExportViewModel
@{
Layout = null;
}
@{
var htmlBulk = string.Empty;
htmlBulk += $"<table><tr><td><div style='text-align:center;font-size:2em;margin:3em 0 5em;width:35%;'>{Model.DocumentTitle}</div></td></tr>";
htmlBulk += $"<tr><td><div style='text-align:center;font-size:1.5em;white-space:pre;'>{Model.BySearchTerms}</div><br/></td></tr></table>";
var sb = new StringBuilder();
using (var writer = new System.IO.StringWriter(sb))
{
(await Component.InvokeAsync("PlacesTable", Model.FieldsToExport)).WriteTo(writer, HtmlEncoder.Default);
htmlBulk += sb.ToString();
}
@Html.Raw(htmlBulk) <-- Should this line be replaced with something else? I mean, if we replace the newlines ("\r\n") with "<br/>" the string "<br/>" is gets concatenated.
}
и компонент бритвы, который содержит шаблон для HTML-таблицы:
@model IEnumerable<Dictionary<string, string>>
<table>
<thead>
<tr>
@if (Model.Any()) {
foreach (var edPlace in Model.First())
{
<th>@edPlace.Key</th>
}
}
</tr>
</thead>
<tbody style="text-align: center; font-size: 12px;">
@foreach (var edPlace in Model)
{
<tr>
@foreach (var kvPair in edPlace)
{
<td>@kvPair.Value</td> <-- this is where newlines might exist, within the 'Value' property, and that are not displayed in the excel downloaded
}
</tr>
}
</tbody>
</table>
и, наконец, фабрика angularjs преобразует HTML-таблицу в Excel.
angular
.module('common')
.factory('Excel', function ($window) {
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"><meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">' +
'<head><!--[if gte mso 9]><xml>' +
'<x:ExcelWorkbook>' +
'<x:ExcelWorksheets>' +
'<x:ExcelWorksheet>' +
'<x:Name>{worksheet}</x:Name>' +
'<x:WorksheetOptions>' +
'<x:DisplayGridlines/>' +
'<x:DisplayRightToLeft/>' + //Important - Set direction of sheet from Right To Left
'</x:WorksheetOptions>' +
'</x:ExcelWorksheet>' +
'</x:ExcelWorksheets>' +
'</x:ExcelWorkbook>' +
'</xml><![endif]--></head><body><table style="font-size:24px;">{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]; }) },
tmplWorkbookXml = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">' + '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>' +
'<Styles>' +
'<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat><Font ss:Size="11"></Font></Style>' +
'<Style ss:ID="CurrencyBold"><NumberFormat ss:Format="Currency"></NumberFormat><Font ss:Size="11" ss:Bold="1"></Font></Style>' +
'<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat><Font ss:Size="11"></Font></Style>' +
'<Style ss:ID="BoldText"><Font ss:Bold="1" ss:Size="11"></Font></Style>' +
'<Style ss:ID="Title"><Font ss:Bold="1" ss:Size="12"></Font></Style>' +
'</Styles>' + '{worksheets}</Workbook>',
tmplWorksheetXml = '<Worksheet ss:Name="{nameWS}"><Table><Column ss:Index="2" ss:Width="110"/> {rows}</Table></Worksheet>',
tmplCellXml = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>';
return {
tableHtmlToExcel: function (tableHtml, worksheetName) {
var ctx = { worksheet: worksheetName, table: tableHtml },
href = uri + base64(format(template, ctx));
return href;
},
some other not related functions...
};
})
.service("exportSrv", ExportSrv);
Так, как мы можем сказать Excel, чтобы отображать новые строки в Excel?
спасибо,
ashilon