npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@rainbow-o23/n6

v1.0.49

Published

o23 excel+csv print

Downloads

238

Readme

Static Badge

ExcelJS CSV for Node.js

Module Formats

o23/n6

o23/n6 provides

  • A pipeline step that converts csv templates to csv, implemented based on CSV-Parse and CSV-stringify,
  • A pipeline step that converts excel template to excel, implemented base on ExcelJS.

CSV Generate Step

Environment Parameters

| Name | Type | Default Value | Comments | |-----------------------------------|---------|------------------------|------------------------------------------------------| | print.csv.temporary.file.keep | boolean | false | Only for debug purpose, never turn on in production. | | print.csv.temporary.file.use | boolean | false | Use temporary file or not. | | print.csv.temporary.lines.fresh | number | 100 | How many lines to fresh to temporary file. | | print.csv.temporary.dir | string | .csv-temporary-files | Temporary file directory. |

Constructor Parameters

| Name | Type | Default Value | Comments | |-------------|---------|---------------|----------| | delimiter | string | , | | | escapeChar | string | " | | | useTempFile | boolean | | |

Request and Response

export interface PrintCsvPipelineStepInFragment {
	template: Buffer | string;
	data: any;
}

export interface PrintCsvPipelineStepOutFragment {
	file: Buffer;
}

An Example

Data

const data = {
	type: 'Test CSV',
	information: [
		{name: 'John', age: 25, birthday: '1998-03-27', addresses: ['address line 1', 'address line 2']},
		{name: 'Jane', age: 27, birthday: '1996-08-12', addresses: ['address line 3']},
		{name: 'Mike', age: 21, birthday: '2002-11-20'}
	],
	policy: [
		{id: 1000001, productName: 'PRDT-001', productInfo: 'PRDT-001-INFO'},
		{id: 1000002, productName: 'PRDT-002', productInfo: 'PRDT-002-INFO'}
	]
};

Template

column1,column2
$type
Name,Age,Birthday
$information.start
$name,$age,$birthday
$addresses.start
$.$
$addresses.end
$information.end
Id,Product Name,Product Info
$policy.start
$id,$productName,$productInfo
$policy.end
  • Supports nested loops,
  • $information.start, $addresses.start, $policy.start represent loop start,
  • $addresses.end, $information.end, $policy.end represent loop end,
  • $name, $age, $birthday represent property,
    • Supports multi-level property names, connected by .. For example, $person.name represents that person is an object and name is a property under person,
  • $.$ represents use loop array itself, in this example, addresses array is a string array,
  • All properties are relative paths, calculated relative to their parent node. Therefore, within a loop, only the values of each element can be accessed.

Output

column1,column2
Test CSV
Name,Age,Birthday
John,25,1998-03-27
address line 1
address line 2
Jane,27,1996-08-12
address line 3
Mike,21,2002-11-20
Id,Product Name,Product Info
1000001,PRDT-001,PRDT-001-INFO
1000002,PRDT-002,PRDT-002-INFO

Performance Benchmark

This benchmark was conducted on the following hardware and environment:

  • CPU: 2.6 GHz 6-Core Intel Core i7,
  • Memory: 64 GB 2667 MHz DDR4,
  • OS: macOS Sonoma 14.2.1,
  • MySQL: 8.2.0,
  • NodeJS: v18.19.0,
  • NPM: v10.2.3.

With scenario:

  • Flow:
    • Load template from database,
    • Print file,
    • Write printed file to database,
    • Return to client,
  • Template size: 0.4kb, 4 lines * 30 columns,
  • Output size: 5.8mb, 10001 lines * 30 columns.

| # | Item | Max CPU Usage | Max Memory Usage | Avg. Response Time (ms) | |---|--------------------------------------|---------------|------------------|-------------------------| | 1 | 100 iterations, single thread | 120% | 600M | 471 | | 2 | 100 iterations, 4 concurrent threads | 150% | 700M | 1444 | | 3 | 100 iterations, 8 concurrent threads | 160% | 750M | 2917 |

Excel Generate Step

Environment Parameters

| Name | Type | Default Value | Comments | |-----------------------------------|---------|--------------------------|------------------------------------------------------| | print.excel.temporary.file.keep | boolean | false | Only for debug purpose, never turn on in production. | | print.excel.temporary.dir | string | .excel-temporary-files | Temporary file directory. |

Request and Response

export interface PrintExcelPipelineStepInFragment {
	/** it is an Excel file, after 2007 */
	template: Buffer;
	data: any;
}

export interface PrintExcelPipelineStepOutFragment {
	file: Buffer;
}

Syntax

Find template and unit test in /test folder, syntax for using an Excel template is as follows:

  • Supports nested loops,
  • $xxx.start represents loop start,
  • $xxx.end represents loop end,
  • Loop flag needs to be defined in the note of the cell and occupy a separate line,
  • Loop flag must be defined in first column,
  • $xxx represents property,
    • Supports multi-level property names, connected by .. For example, $person.name represents that person is an object and name is a property under person,
  • $.$ represents use loop array itself,
  • All properties are relative paths, calculated relative to their parent node. Therefore, within a loop, only the values of each element can be accessed.

Want TypeOrm Cursor?

Simply let the loop data be an instanceof TypeOrmDataIterator, see test case.

Feel free to use your own LoopDataIterator.

Known Issues

  • Cannot apply auto filter into merged cells correctly, each cell will display a filter, which should only be displayed on the last cell.
  • Cannot copy theme correctly, please use the specified color and do not choose from the suggested theme colors provided by Excel.
  • ExcelJS does not read the note data of empty cells. Therefore, when the loop flag appears on an empty cell, it needs to be specially marked with the $.$del flag.

Performance Benchmark

This benchmark was conducted on the following hardware and environment:

  • CPU: 2.6 GHz 6-Core Intel Core i7,
  • Memory: 64 GB 2667 MHz DDR4,
  • OS: macOS Sonoma 14.2.1,
  • MySQL: 8.2.0,
  • NodeJS: v18.19.0,
  • NPM: v10.2.3.

With scenario:

  • Flow:
    • Load template from database,
    • Print file,
    • Write printed file to database,
    • Return to client,
  • Template size: 12kb, 2 lines * 30 columns,
  • Output size: 4.1mb, 10001 lines * 30 columns.

| # | Item | Max CPU Usage | Max Memory Usage | Avg. Response Time (ms) | |---|--------------------------------------|---------------|------------------|-------------------------| | 1 | 100 iterations, single thread | 120% | 550M | 945 | | 2 | 100 iterations, 4 concurrent threads | 150% | 850M | 2878 | | 3 | 100 iterations, 8 concurrent threads | 170% | 1000M | 5718 |