@jsreport/jsreport-xlsx
Advanced tools
Comparing version 3.1.0 to 3.2.0
const extend = require('node.extend.without.arrays') | ||
const serialize = require('./serialize') | ||
const serialize = require('./transformation/serialize') | ||
@@ -4,0 +4,0 @@ module.exports = (reporter, definition) => { |
const fs = require('fs') | ||
const fallback = require('./fallback.js') | ||
const jsonToXml = require('./jsonToXml.js') | ||
const stream = require('stream') | ||
const zlib = require('zlib') | ||
const merge = require('merge2') | ||
const { response, serializeOfficeXmls } = require('@jsreport/office') | ||
const { response } = require('@jsreport/office') | ||
const stringToStream = (str) => { | ||
const s = new stream.Readable() | ||
s.push(str) | ||
s.push(null) | ||
return s | ||
} | ||
module.exports = async (reporter, definition, req, res) => { | ||
reporter.logger.debug('Parsing xlsx content', req) | ||
const generate = require('./generation') | ||
const xlsxOutputPath = await generate(reporter, definition, req, res) | ||
const contentString = res.content.toString() | ||
const $xlsxOriginalContent = req.data.$xlsxOriginalContent || '' | ||
if ($xlsxOriginalContent.trim() !== '') { | ||
const transform = require('./transformation') | ||
let $xlsxTemplate | ||
let $files | ||
res.content = xlsxOutputPath | ||
try { | ||
const content = JSON.parse(contentString) | ||
$xlsxTemplate = content.$xlsxTemplate | ||
$files = content.$files | ||
} catch (e) { | ||
reporter.logger.warn('Unable to parse xlsx template JSON string (maybe you are missing {{{xlsxPrint}}} at the end?): \n' + contentString.substring(0, 100) + '... \n' + e.stack, req) | ||
return fallback(reporter, definition, req, res) | ||
await transform(reporter, definition, req, res) | ||
} else { | ||
res.stream = fs.createReadStream(xlsxOutputPath) | ||
} | ||
const files = Object.keys($xlsxTemplate).map((k) => { | ||
if (k.includes('xl/media/') || k.includes('.bin')) { | ||
return { | ||
path: k, | ||
data: Buffer.from($xlsxTemplate[k], 'base64') | ||
} | ||
} | ||
if (k.includes('.xml')) { | ||
const xmlAndFiles = jsonToXml($xlsxTemplate[k]) | ||
const fullXml = xmlAndFiles.xml | ||
if (fullXml.indexOf('&&') < 0) { | ||
return { | ||
path: k, | ||
data: Buffer.from(fullXml, 'utf8') | ||
} | ||
} | ||
const xmlStream = merge() | ||
if (fullXml.indexOf('&&') < 0) { | ||
return { | ||
path: k, | ||
data: Buffer.from(fullXml, 'utf8') | ||
} | ||
} | ||
let xml = fullXml | ||
while (xml) { | ||
const separatorIndex = xml.indexOf('&&') | ||
if (separatorIndex < 0) { | ||
xmlStream.add(stringToStream(xml)) | ||
xml = '' | ||
continue | ||
} | ||
xmlStream.add(stringToStream(xml.substring(0, separatorIndex))) | ||
xmlStream.add(fs.createReadStream($files[xmlAndFiles.files.shift()]).pipe(zlib.createInflate())) | ||
xml = xml.substring(separatorIndex + '&&'.length) | ||
} | ||
return { | ||
path: k, | ||
data: xmlStream | ||
} | ||
} | ||
return { | ||
path: k, | ||
data: Buffer.from($xlsxTemplate[k], 'utf8') | ||
} | ||
}) | ||
await serializeOfficeXmls({ reporter, files, officeDocumentType: 'xlsx' }, req, res) | ||
return response({ | ||
await response({ | ||
previewOptions: definition.options.preview, | ||
@@ -92,0 +21,0 @@ officeDocumentType: 'xlsx', |
const fs = require('fs').promises | ||
const path = require('path') | ||
let defaultXlsxTemplate | ||
module.exports = (reporter, definition) => { | ||
@@ -22,2 +20,7 @@ reporter.options.sandbox.modules.push({ | ||
reporter.options.sandbox.modules.push({ | ||
alias: 'string-pixel-width', | ||
path: require.resolve('string-pixel-width') | ||
}) | ||
if (reporter.options.sandbox.allowedModules !== '*') { | ||
@@ -32,11 +35,19 @@ reporter.options.sandbox.allowedModules.push('path') | ||
let helpersScript | ||
let helpersGenerationScript | ||
let helpersTransformationScript | ||
reporter.initializeListeners.add(definition.name, async () => { | ||
helpersScript = await fs.readFile(path.join(__dirname, '../static/helpers.js'), 'utf8') | ||
helpersGenerationScript = await fs.readFile(path.join(__dirname, '../static/helpersGeneration.js'), 'utf8') | ||
helpersTransformationScript = await fs.readFile(path.join(__dirname, '../static/helpersTransformation.js'), 'utf8') | ||
}) | ||
reporter.registerHelpersListeners.add(definition.name, (req) => { | ||
if (req.template.recipe === 'xlsx') { | ||
return helpersScript | ||
return `${helpersGenerationScript}\n\n${helpersTransformationScript}` | ||
}) | ||
reporter.beforeRenderListeners.insert({ before: 'templates' }, `${definition.name}-next`, (req) => { | ||
if (req.template.recipe === 'xlsx' && !req.template.name && !req.template.shortid && !req.template.content) { | ||
// templates extension otherwise complains that the template is empty | ||
// but that is fine for this recipe | ||
req.template.content = ' ' | ||
} | ||
@@ -50,47 +61,7 @@ }) | ||
const serialize = require('./serialize.js') | ||
const parse = serialize.parse | ||
req.data = req.data || {} | ||
req.data.$xlsxOriginalContent = req.template.content | ||
const findTemplate = async () => { | ||
if ( | ||
(!req.template.xlsx || (!req.template.xlsx.templateAssetShortid && !req.template.xlsx.templateAsset)) | ||
) { | ||
if (defaultXlsxTemplate) { | ||
return Promise.resolve(defaultXlsxTemplate) | ||
} | ||
req.template.content = '' | ||
return fs.readFile(path.join(__dirname, '../static/defaultXlsxTemplate.json')).then((content) => JSON.parse(content)) | ||
} | ||
if (req.template.xlsx && req.template.xlsx.templateAsset && req.template.xlsx.templateAsset.content) { | ||
return parse(Buffer.from(req.template.xlsx.templateAsset.content, req.template.xlsx.templateAsset.encoding || 'utf8')) | ||
} | ||
let docs = [] | ||
let xlsxTemplateShortid | ||
if (req.template.xlsx && req.template.xlsx.templateAssetShortid) { | ||
xlsxTemplateShortid = req.template.xlsx.templateAssetShortid | ||
docs = await reporter.documentStore.collection('assets').find({ shortid: xlsxTemplateShortid }, req) | ||
} | ||
if (!docs.length) { | ||
if (!xlsxTemplateShortid) { | ||
throw reporter.createError('Unable to find xlsx template. xlsx template not specified', { | ||
statusCode: 404 | ||
}) | ||
} | ||
throw reporter.createError(`Unable to find xlsx template with shortid ${xlsxTemplateShortid}`, { | ||
statusCode: 404 | ||
}) | ||
} | ||
return parse(docs[0].content) | ||
} | ||
const template = await findTemplate() | ||
req.data = req.data || {} | ||
req.data.$xlsxTemplate = template | ||
req.data.$xlsxModuleDirname = path.join(__dirname, '../') | ||
@@ -101,3 +72,6 @@ req.data.$tempAutoCleanupDirectory = reporter.options.tempAutoCleanupDirectory | ||
req.data.$numberOfParsedAddIterations = definition.options.numberOfParsedAddIterations == null ? 50 : definition.options.numberOfParsedAddIterations | ||
// this allows the data generated in the helpers to continue to be persisted outside of the sandbox | ||
req.data.$files = [] | ||
req.data.$buffers = {} | ||
}) | ||
} |
{ | ||
"name": "@jsreport/jsreport-xlsx", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "jsreport recipe rendering excels directly from open xml", | ||
@@ -33,15 +33,23 @@ "keywords": [ | ||
"@jsreport/office": "3.0.0", | ||
"@xmldom/xmldom": "0.7.0", | ||
"js-excel-date-convert": "1.0.2", | ||
"lodash": "4.17.21", | ||
"merge2": "1.3.0", | ||
"mkdirp": "0.5.5", | ||
"msexcel-builder-extended": "0.0.8", | ||
"moment": "2.29.3", | ||
"node.extend.without.arrays": "1.1.6", | ||
"semaphore-async-await": "1.5.1", | ||
"string-pixel-width": "1.10.0", | ||
"string-replace-async": "2.0.0", | ||
"unescape": "1.0.1", | ||
"uuid": "8.3.2", | ||
"xlsx-coordinates": "1.0.1", | ||
"xml2js-preserve-spaces": "0.0.1" | ||
}, | ||
"devDependencies": { | ||
"@jsreport/jsreport-assets": "3.1.0", | ||
"@jsreport/jsreport-core": "3.2.0", | ||
"@jsreport/jsreport-handlebars": "3.0.0", | ||
"@jsreport/studio-dev": "3.0.1", | ||
"@jsreport/jsreport-assets": "3.4.1", | ||
"@jsreport/jsreport-components": "3.2.0", | ||
"@jsreport/jsreport-core": "3.5.0", | ||
"@jsreport/jsreport-handlebars": "3.1.0", | ||
"@jsreport/studio-dev": "3.1.0", | ||
"cross-env": "6.0.3", | ||
@@ -48,0 +56,0 @@ "handlebars": "4.7.7", |
@@ -10,2 +10,7 @@ # @jsreport/jsreport-xlsx | ||
### 3.2.0 | ||
- add support for generating xlsx based on handlebars tags present directly in a xlsx template file | ||
- the old way of generating xlsx (transforming/assembling xml using templating engines and helpers) is still supported and it is now executed taking the generated xlsx as input | ||
### 3.0.1 | ||
@@ -12,0 +17,0 @@ |
@@ -6,2 +6,40 @@ import XlsxTemplateProperties from './XlsxTemplateProperties.js' | ||
Studio.entityEditorComponentKeyResolvers.push((entity) => { | ||
if (entity.__entitySet === 'templates' && entity.recipe === 'xlsx') { | ||
let officeAsset | ||
if (entity.xlsx != null && entity.xlsx.templateAssetShortid != null) { | ||
officeAsset = Studio.getEntityByShortid(entity.xlsx.templateAssetShortid, false) | ||
} | ||
let initialCodeActive = true | ||
if ( | ||
officeAsset != null && | ||
(entity.content == null || entity.content === '') | ||
) { | ||
initialCodeActive = false | ||
} | ||
return { | ||
key: 'assets', | ||
entity: officeAsset, | ||
props: { | ||
icon: 'fa-link', | ||
embeddingCode: '', | ||
initialCodeActive, | ||
codeEntity: { | ||
_id: entity._id, | ||
shortid: entity.shortid, | ||
name: entity.name, | ||
content: entity.content, | ||
helpers: entity.helpers | ||
}, | ||
displayName: `xlsx asset: ${officeAsset != null ? officeAsset.name : '<none>'}`, | ||
emptyMessage: 'No xlsx asset assigned, please add a reference to a xlsx asset in the properties' | ||
} | ||
} | ||
} | ||
}) | ||
Studio.runListeners.push((request, entities) => { | ||
@@ -8,0 +46,0 @@ if (request.template.recipe !== 'xlsx') { |
@@ -114,2 +114,37 @@ /******/ (function(modules) { // webpackBootstrap | ||
_jsreportStudio2.default.entityEditorComponentKeyResolvers.push(function (entity) { | ||
if (entity.__entitySet === 'templates' && entity.recipe === 'xlsx') { | ||
var officeAsset = void 0; | ||
if (entity.xlsx != null && entity.xlsx.templateAssetShortid != null) { | ||
officeAsset = _jsreportStudio2.default.getEntityByShortid(entity.xlsx.templateAssetShortid, false); | ||
} | ||
var initialCodeActive = true; | ||
if (officeAsset != null && (entity.content == null || entity.content === '')) { | ||
initialCodeActive = false; | ||
} | ||
return { | ||
key: 'assets', | ||
entity: officeAsset, | ||
props: { | ||
icon: 'fa-link', | ||
embeddingCode: '', | ||
initialCodeActive: initialCodeActive, | ||
codeEntity: { | ||
_id: entity._id, | ||
shortid: entity.shortid, | ||
name: entity.name, | ||
content: entity.content, | ||
helpers: entity.helpers | ||
}, | ||
displayName: 'xlsx asset: ' + (officeAsset != null ? officeAsset.name : '<none>'), | ||
emptyMessage: 'No xlsx asset assigned, please add a reference to a xlsx asset in the properties' | ||
} | ||
}; | ||
} | ||
}); | ||
_jsreportStudio2.default.runListeners.push(function (request, entities) { | ||
@@ -255,7 +290,2 @@ if (request.template.recipe !== 'xlsx') { | ||
{ className: 'form-group' }, | ||
_react2.default.createElement( | ||
'label', | ||
null, | ||
'xlsx asset' | ||
), | ||
_react2.default.createElement(EntityRefSelect, { | ||
@@ -294,3 +324,3 @@ headingLabel: 'Select xlsx template', | ||
if (!entity.xlsx || !entity.xlsx.templateAssetShortid) { | ||
return 'xlsx template'; | ||
return 'xlsx'; | ||
} | ||
@@ -303,3 +333,3 @@ | ||
if (!foundAssets.length) { | ||
return 'xlsx template'; | ||
return 'xlsx'; | ||
} | ||
@@ -309,3 +339,3 @@ | ||
return 'xlsx template: ' + name; | ||
return 'xlsx asset: ' + name; | ||
} | ||
@@ -312,0 +342,0 @@ }]); |
@@ -16,3 +16,3 @@ import React, { Component } from 'react' | ||
) { | ||
return 'xlsx template' | ||
return 'xlsx' | ||
} | ||
@@ -23,3 +23,3 @@ | ||
if (!foundAssets.length) { | ||
return 'xlsx template' | ||
return 'xlsx' | ||
} | ||
@@ -29,3 +29,3 @@ | ||
return 'xlsx template: ' + name | ||
return 'xlsx asset: ' + name | ||
} | ||
@@ -76,3 +76,2 @@ | ||
<div className='form-group'> | ||
<label>xlsx asset</label> | ||
<EntityRefSelect | ||
@@ -79,0 +78,0 @@ headingLabel='Select xlsx template' |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
196020
34
4219
22
15
11
7
5
+ Added@xmldom/xmldom@0.7.0
+ Addedjs-excel-date-convert@1.0.2
+ Addedmoment@2.29.3
+ Addedsemaphore-async-await@1.5.1
+ Addedstring-pixel-width@1.10.0
+ Addedstring-replace-async@2.0.0
+ Addedunescape@1.0.1
+ Addedxlsx-coordinates@1.0.1
+ Added@xmldom/xmldom@0.7.0(transitive)
+ Addedextend-shallow@2.0.1(transitive)
+ Addedis-extendable@0.1.1(transitive)
+ Addedjs-excel-date-convert@1.0.2(transitive)
+ Addedlodash.deburr@4.1.0(transitive)
+ Addedmoment@2.29.3(transitive)
+ Addedsemaphore-async-await@1.5.1(transitive)
+ Addedstring-pixel-width@1.10.0(transitive)
+ Addedstring-replace-async@2.0.0(transitive)
+ Addedunescape@1.0.1(transitive)
+ Addedxlsx-coordinates@1.0.1(transitive)
- Removedmsexcel-builder-extended@0.0.8
- Removedarchiver@2.1.1(transitive)
- Removedarchiver-utils@1.3.0(transitive)
- Removedasync@2.1.2(transitive)
- Removedbl@1.2.3(transitive)
- Removedbuffer-alloc@1.2.0(transitive)
- Removedbuffer-alloc-unsafe@1.1.0(transitive)
- Removedbuffer-fill@1.0.0(transitive)
- Removedcompress-commons@1.2.2(transitive)
- Removedcrc@3.8.0(transitive)
- Removedcrc32-stream@2.0.0(transitive)
- Removedfs-extra@1.0.0(transitive)
- Removedjsonfile@2.4.0(transitive)
- Removedklaw@1.3.1(transitive)
- Removedmsexcel-builder-extended@0.0.8(transitive)
- Removednormalize-path@2.1.1(transitive)
- Removedremove-trailing-separator@1.1.0(transitive)
- Removedtar-stream@1.6.2(transitive)
- Removedto-buffer@1.1.1(transitive)
- Removedxmlbuilder@8.2.2(transitive)
- Removedxtend@4.0.2(transitive)
- Removedzip-stream@1.2.0(transitive)