typescript - Usando Angular 2 para generar archivos Docx
Estoy usando Angular2 y quiero generar un archivo docx usando un objeto. Quiero que mi archivo docx contenga pies de página, encabezados, tablas, etc. La mejor solución que se me ocurre es primero crear un archivo HTML, y luego convertirlo en un archivo docx. Pero esto no parece correcto. ¿Hay una manera más fácil y conveniente de hacer lo que quiero hacer? Aquí está el método que uso:
exportAsDoc() {
const preHtml = '<html xmlns:o=\'urn:schemas-microsoft-com:office:office\' ' + '' +
' xmlns:w=\'urn:schemas-microsoft-com:office:word\' xmlns=\'http://www.w3.org/TR/REC-html40\'><head><meta charset=\'utf-8\'>' +
'<title>Export HTML To Doc</title></head><body>';
const postHtml = '</body></html>';
let innerHtml = '';
// Specify file name
const filename = this.respSheet.title + '.doc';
const respSheetKpis = this.respSheet.sheet_kpis;
respSheetKpis.forEach(x => {
const footer = '<p style="text-align: center">' + x.kpi.name + ' - ' + x.kpiValue + '</p>';
innerHtml += footer;
x.sheet_kpi_dimensions.forEach(dimension => {
if (dimension.dimension !== undefined) innerHtml += dimension.dimension.name;
let table = '<table>\n' +
' <tr>\n' +
' <th>Istatistik adi</th>\n' +
' <th>Degeri</th> \n' +
' </tr>\n';
const data = dimension.data;
if (data !== undefined) {
for ( let i = 0 ; i < data.length ; i ++ ) {
table += ' <tr>\n' +
' <th>' + data[ i ].title + '</th>\n' +
' <th>' + data[ i ].value + '</th> \n' +
' </tr>\n';
}
table += '</table>';
innerHtml += table;
}
})
});
const html = preHtml + innerHtml + postHtml;
const blob = new Blob(['\ufeff', html], {
type: 'application/msword'
});
// Specify link url
const url = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(html);
// Create download link element
const downloadLink = document.createElement('a');
document.body.appendChild(downloadLink);
if (navigator.msSaveOrOpenBlob ) {
navigator.msSaveOrOpenBlob(blob, filename);
} else {
// Create a link to the file
downloadLink.href = url;
// Setting the file name
downloadLink.download = filename;
// triggering the function
downloadLink.click();
}
document.body.removeChild(downloadLink);
}
Respuesta #1
Demasiado tarde para la respuesta, pero esto podría ser útil para alguien más. Una forma de implementar esto es usando docx.js
He añadido un ejemplo sencillo y un enlace al ejemplo y a la documentación
https://stackblitz.com/edit/angular-afvxtz
https://docx.js.org/#/
Archivo TS:
import { Component } from '@angular/core';
import { Packer } from 'docx';
import { saveAs } from 'file-saver/FileSaver';
import { DocumentCreator } from './cv-generator';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
public download(): void {
const documentCreator = new DocumentCreator();
const doc = documentCreator.create();
doc.createParagraph("Test heading1, bold and italicized").heading1();
doc.createParagraph("Some simple content");
const packer = new Packer();
packer.toBlob(doc).then(blob => {
console.log(blob);
saveAs(blob, "example.docx");
console.log("Document created successfully");
});
}
}
archivo cv-generator.ts:
import { Document, Paragraph, Packer, TextRun } from 'docx';
export class DocumentCreator {
create() {
const title = 'EXECUTIVE SUMMARY';
const document = new Document();
document.addParagraph(new Paragraph(title).title());
document.addParagraph(this.createHeading('Exception Overview'));
return document;
}
createHeading(text) {
return new Paragraph(text).heading1().thematicBreak();
}
}
HTML :
<button class="em-primary-button" (click)="download()">Download file</button>
Respuesta #2
En mi opinión, la herramienta más sencilla para trabajar en la generación de documentos en el front-end es Docx.js. Creo que puede ayudarte a resolver tu problema.
En este proyecto generas un HTML simple usando un código de Javascript (o typescript), y lo guardas como un archivo Docx. Algo así:
<script>
function exportAsDoc() {
var content = '<!DOCTYPE html>';
var items = [
{col1: "foo", col2: "bar"}
];
content += "<html><body><table>";
content += "<tr>";
content += "<th>col1</th><th>col2</th>";
content += "</tr>";
for (var i=0; i<items.length; i++) {
content += "<tr>";
content += "<td>" + items[i].col1 + "</td>";
content += "<td>" + items[i].col2 + "</td>";
content += "</tr>";
}
content += "</table></body></html>";
var converted = htmlDocx.asBlob(content, {orientation: "landscape"});
console.log(converted);
saveAs(converted, 'test.docx');
}
</script>
En el sitio web del proyecto tienes un ejemplo completo usando un editor en línea. Solo sigue el ejemplo y adáptalo a tu proyecto
http://evidenceprime.github.io/html-docx-js/
