create static method
Cria o arquivo XLSX compactado retornando os bytes.
Implementation
static Uint8List create(Map<String, dynamic> workbook) {
const xmlHead = '<?xml version="1.0" encoding="UTF-8"?>';
final zip = MinimalZip();
// Relações básicas
final types = [
{
'Extension': 'rels',
'ContentType':
'application/vnd.openxmlformats-package.relationships+xml'
},
{'Extension': 'xml', 'ContentType': 'application/xml'},
{
'PartName': '/xl/styles.xml',
'ContentType':
'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'
},
{
'PartName': '/xl/workbook.xml',
'ContentType':
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'
}
];
final rels = [
{
'Id': 'rId0',
'Type':
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
'Target': 'styles.xml'
}
];
final sheets = workbook['sheets'] as List<dynamic>;
final sheetsXml = StringBuffer();
// Estilos fixos mínimos
const stylesXml =
'''<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<numFmts count="2">
<numFmt numFmtId="164" formatCode="yyyy-mm-dd"/>
<numFmt numFmtId="165" formatCode="yyyy-mm-dd hh:mm:ss"/>
</numFmts>
<fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><sz val="11"/><name val="Calibri"/><b/></font></fonts>
<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>
<borders count="1"><border/></borders>
<cellXfs count="4">
<xf fontId="0" applyFont="1"/>
<xf numFmtId="164" applyNumberFormat="1"/>
<xf numFmtId="165" applyNumberFormat="1"/>
<xf numFmtId="0" fontId="1" applyFont="1"/>
</cellXfs>
</styleSheet>''';
for (int i = 0; i < sheets.length; i++) {
final int sheetId = i + 1;
final sheet = sheets[i] as Map<String, dynamic>;
final String sheetName = sheet['name'] ?? 'Sheet$sheetId';
final List<List<dynamic>> data =
(sheet['data'] as List<dynamic>).cast<List<dynamic>>();
final partName = '/xl/worksheets/sheet$sheetId.xml';
types.add({
'PartName': partName,
'ContentType':
'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'
});
rels.add({
'Id': 'rId$sheetId',
'Type':
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
'Target': 'worksheets/sheet$sheetId.xml'
});
sheetsXml.write(_toXml('sheet',
{'name': sheetName, 'sheetId': sheetId, 'r:id': 'rId$sheetId'}));
final sheetDataXml = StringBuffer();
int rowIndex = 1;
for (var row in data) {
final rowXml = StringBuffer();
for (int col = 0; col < row.length; col++) {
final val = row[col];
if (val == null) continue;
final ref = '${_toCol(col)}$rowIndex';
if (val is String) {
rowXml.write(
'<c r="$ref" t="inlineStr"><is><t>${_escape(val)}</t></is></c>');
} else if (val is num) {
rowXml.write('<c r="$ref"><v>$val</v></c>');
} else if (val is bool) {
rowXml.write('<c r="$ref" t="b"><v>${val ? 1 : 0}</v></c>');
} else if (val is DateTime) {
final double excelDate =
val.difference(_excelEpoch).inMilliseconds / 86400000.0;
// s="1" aponta para o formato de data yyyy-mm-dd
rowXml.write(
'<c r="$ref" s="1"><v>${excelDate.toStringAsFixed(6)}</v></c>');
}
}
if (rowXml.isNotEmpty) {
sheetDataXml.write('<row r="$rowIndex">$rowXml</row>');
}
rowIndex++;
}
final content = StringBuffer()
..write(xmlHead)
..write(
'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">')
..write('<sheetData>$sheetDataXml</sheetData>')
..write('</worksheet>');
zip.addFile(
'xl/worksheets/sheet$sheetId.xml', utf8.encode(content.toString()));
}
// [Content_Types].xml
final typesXml = StringBuffer();
for (var t in types) {
if (t.containsKey('Extension')) {
typesXml.write(_toXml('Default', t));
} else {
typesXml.write(_toXml('Override', t));
}
}
zip.addFile(
'[Content_Types].xml',
utf8.encode(
'$xmlHead<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">$typesXml</Types>'));
// _rels/.rels
zip.addFile(
'_rels/.rels',
utf8.encode(
'$xmlHead<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>'));
// xl/_rels/workbook.xml.rels
final relsXml = StringBuffer();
for (var r in rels) {
relsXml.write(_toXml('Relationship', r));
}
zip.addFile(
'xl/_rels/workbook.xml.rels',
utf8.encode(
'$xmlHead<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">$relsXml</Relationships>'));
// xl/styles.xml
zip.addFile('xl/styles.xml', utf8.encode(xmlHead + stylesXml));
// xl/workbook.xml
zip.addFile(
'xl/workbook.xml',
utf8.encode(
'$xmlHead<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets>$sheetsXml</sheets></workbook>'));
return zip.finish();
}