diff --git a/lib/file.js b/lib/file.js index 55d11967..e7b4ca77 100644 --- a/lib/file.js +++ b/lib/file.js @@ -25,6 +25,15 @@ var file = { }); }); }); + }, + /** + * isZippedBuffer return callback(true) if the buffer is zipped + * @param {Buffer} buffer file path + * @param {Function} callback(err, isZipped) + */ + isZippedBuffer : function (buffer, callback) { + var _buf = buffer; + callback(null, (buffer.slice(0, 2).toString() === 'PK')); }, /** @@ -47,7 +56,7 @@ var file = { /** * Unzip a file - * @param {String} filePath file to unzip + * @param {String} filePath file or buffer to unzip * @param {Function} callback(err, files) files is an array of files ['name':'filename', 'buffer':Buffer] */ unzip : function (filePath, callback) { @@ -130,9 +139,44 @@ var file = { _zip.end(); }, + /** + * + * @param {Buffer} buffer document as a buffer + * @param {*} callback + * @returns + */ + openTemplateBuffer : function (buffer, callback) { + file.isZippedBuffer(buffer, function(err, isZipped) { + if (err) return callback(err); + var _template = { + isZipped, + filename : 'template-from-buffer', + embeddings : [], + files : [] + }; + if (isZipped === true) { + var _filesToUnzip = [{ + name : '', + data : buffer + }]; + return unzipFiles(_template, _filesToUnzip, callback); + } + else { + var _file = { + name : 'file-from-buffer', + data : buffer, + isMarked : true, + parent : '' + }; + _template.files.push(_file); + return callback(err, _template); + } + }) + }, + /** * Open a template (zipped or not). It will find the template and convert the buffer into strings if it contains xml - * @param {String} templateId template name (with or without the path) + * @param {String} templateId template name (with or without the path) or buffer. When buffer is used, extension option must be provided * @param {Function} callback(err, template) */ openTemplate : function (templateId, callback) { @@ -142,6 +186,9 @@ var file = { embeddings : [], files : [] }; + if(Buffer.isBuffer(templateId)){ + return file.openTemplateBuffer(templateId, callback) + } if (templateId instanceof Object) { // accept already dezipped files (for test purpose) return callback(null, templateId); diff --git a/lib/index.js b/lib/index.js index 9819bd57..8a8ec490 100644 --- a/lib/index.js +++ b/lib/index.js @@ -194,9 +194,8 @@ var carbone = { return callback(err, null); } // Determine the template extension. - var _extension = file.detectType(template); // It takes the user defined one, or use the file type. - options.extension = optionsRaw.extension || _extension; + options.extension = optionsRaw.extension || file.detectType(template); if (options.extension === null) { return callback('Unknown input file type. It should be a docx, xlsx, pptx, odt, ods, odp, xhtml, html or an xml file'); } diff --git a/test/test.file.js b/test/test.file.js index bcbf09dc..f1c44678 100644 --- a/test/test.file.js +++ b/test/test.file.js @@ -138,6 +138,24 @@ describe('file', function () { }); }); }); + + describe('isZippedBuffer', function () { + it('should return true if the file is zipped', function (done) { + var buffer = fs.readFileSync(path.resolve('./test/datasets/test_word_render_A.docx')); + file.isZippedBuffer(buffer, function (err, isZipped) { + helper.assert(isZipped, true); + done(); + }); + }); + it('should return false if the file is not zipped', function (done) { + var buffer = fs.readFileSync(path.resolve('./test/datasets/test_word_render_2003_XML.xml')); + file.isZippedBuffer(buffer, function (err, isZipped) { + helper.assert(isZipped, false); + done(); + }); + }); + }); + describe('unzip', function () { it('should unzip a file and return a array which contain its content', function (done) { @@ -493,6 +511,31 @@ describe('file', function () { done(); }); }); + + it('should open embedded xlsx buffer', function (done) { + const buffer = fs.readFileSync(path.resolve(__dirname, 'datasets', 'test_word_with_embedded_excel.docx')) + file.openTemplate(buffer, function (err, template) { + helper.assert(err, null); + helper.assert(template.isZipped, true); + helper.assert(template.files.length, 29); + helper.assert(template.embeddings.length, 1); + helper.assert(template.embeddings, ['word/embeddings/Feuille_de_calcul_Microsoft_Excel1.xlsx']); + var _filesFromDocx = template.files.filter((file) => { + return file.parent === ''; + }); + helper.assert(_filesFromDocx.length, 16); + var _filesFromXslx = template.files.filter((file) => { + return file.parent === 'word/embeddings/Feuille_de_calcul_Microsoft_Excel1.xlsx'; + }); + helper.assert(_filesFromXslx.length, 13); + var _oneFileOfXlsx = _filesFromXslx.filter((file) => { + return file.name === 'xl/tables/table1.xml'; + }); + helper.assert(_oneFileOfXlsx.length, 1); + helper.assert(/Tableau1/.test(_oneFileOfXlsx[0].data), true); + done(); + }); + }); /* it.skip('should detect files which contains markers (not all xml)');*/ });