isahaq-barcode 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +29 -29
- package/.prettierignore +11 -0
- package/.prettierrc +11 -0
- package/README.md +596 -549
- package/bin/generate.js +274 -274
- package/eslint.config.js +66 -68
- package/examples/basic-usage.js +58 -58
- package/examples/batch-example.json +56 -56
- package/examples/express-server.js +163 -159
- package/index.js +134 -134
- package/jest.config.js +13 -13
- package/package.json +27 -15
- package/src/builders/QrCodeBuilder.js +401 -401
- package/src/renderers/HTMLRenderer.js +212 -212
- package/src/renderers/PDFRenderer.js +184 -184
- package/src/renderers/PNGRenderer.js +123 -123
- package/src/renderers/RenderFormats.js +87 -87
- package/src/renderers/SVGRenderer.js +221 -221
- package/src/services/BarcodeService.js +175 -175
- package/src/types/BarcodeTypes.js +195 -195
- package/src/validators/Validator.js +352 -352
- package/tests/BarcodeGenerator.test.js +187 -187
- package/tests/BarcodeService.test.js +76 -76
- package/tests/QrCodeBuilder.test.js +130 -130
- package/tests/setup.js +59 -59
|
@@ -1,184 +1,184 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PDF Renderer - Renders barcodes as PDF
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const PDFDocument = require('pdfkit');
|
|
6
|
-
|
|
7
|
-
class PDFRenderer {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.defaultOptions = {
|
|
10
|
-
width: 2,
|
|
11
|
-
height: 100,
|
|
12
|
-
displayValue: true,
|
|
13
|
-
fontSize: 20,
|
|
14
|
-
textAlign: 'center',
|
|
15
|
-
textPosition: 'bottom',
|
|
16
|
-
textMargin: 2,
|
|
17
|
-
background: '#ffffff',
|
|
18
|
-
lineColor: '#000000',
|
|
19
|
-
margin: 10,
|
|
20
|
-
marginTop: 10,
|
|
21
|
-
marginBottom: 10,
|
|
22
|
-
marginLeft: 10,
|
|
23
|
-
marginRight: 10,
|
|
24
|
-
pageWidth: 612,
|
|
25
|
-
pageHeight: 792,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Render a barcode as PDF
|
|
31
|
-
* @param {string} data - The data to encode
|
|
32
|
-
* @param {string} type - The barcode type
|
|
33
|
-
* @param {Object} options - Render options
|
|
34
|
-
* @returns {Buffer} PDF buffer
|
|
35
|
-
*/
|
|
36
|
-
render(data, type, options = {}) {
|
|
37
|
-
try {
|
|
38
|
-
// Merge options with defaults
|
|
39
|
-
const renderOptions = { ...this.defaultOptions, ...options };
|
|
40
|
-
|
|
41
|
-
// Create PDF document
|
|
42
|
-
const doc = new PDFDocument({
|
|
43
|
-
size: [renderOptions.pageWidth, renderOptions.pageHeight],
|
|
44
|
-
margins: {
|
|
45
|
-
top: renderOptions.marginTop,
|
|
46
|
-
bottom: renderOptions.marginBottom,
|
|
47
|
-
left: renderOptions.marginLeft,
|
|
48
|
-
right: renderOptions.marginRight,
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Collect PDF data
|
|
53
|
-
const chunks = [];
|
|
54
|
-
doc.on('data',
|
|
55
|
-
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
doc.on('end', () => {
|
|
58
|
-
const pdfBuffer = Buffer.concat(chunks);
|
|
59
|
-
resolve(pdfBuffer);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
doc.on('error', reject);
|
|
63
|
-
|
|
64
|
-
// Add barcode to PDF
|
|
65
|
-
this.addBarcodeToPDF(doc, data, type, renderOptions);
|
|
66
|
-
|
|
67
|
-
// Finalize PDF
|
|
68
|
-
doc.end();
|
|
69
|
-
});
|
|
70
|
-
} catch (error) {
|
|
71
|
-
throw new Error(`PDF rendering failed: ${error.message}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Add barcode to PDF document
|
|
77
|
-
* @param {PDFDocument} doc - PDF document
|
|
78
|
-
* @param {string} data - The data to encode
|
|
79
|
-
* @param {string} type - The barcode type
|
|
80
|
-
* @param {Object} options - Render options
|
|
81
|
-
*/
|
|
82
|
-
addBarcodeToPDF(doc, data, type, options) {
|
|
83
|
-
// Set background color
|
|
84
|
-
doc.rect(0, 0, options.pageWidth, options.pageHeight);
|
|
85
|
-
doc.fillColor(options.background);
|
|
86
|
-
doc.fill();
|
|
87
|
-
|
|
88
|
-
// Calculate position
|
|
89
|
-
const x = options.marginLeft;
|
|
90
|
-
const y = options.marginTop;
|
|
91
|
-
|
|
92
|
-
if (type === 'qrcode') {
|
|
93
|
-
this.addQRCodeToPDF(doc, data, x, y, options);
|
|
94
|
-
} else {
|
|
95
|
-
this.addLinearBarcodeToPDF(doc, data, type, x, y, options);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Add text if displayValue is true
|
|
99
|
-
if (options.displayValue) {
|
|
100
|
-
doc.fontSize(options.fontSize);
|
|
101
|
-
doc.fillColor(options.lineColor);
|
|
102
|
-
doc.text(data, x, y + options.height + options.textMargin, {
|
|
103
|
-
align: options.textAlign,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Add QR Code to PDF
|
|
110
|
-
* @param {PDFDocument} doc - PDF document
|
|
111
|
-
* @param {string} data - The data to encode
|
|
112
|
-
* @param {number} x - X position
|
|
113
|
-
* @param {number} y - Y position
|
|
114
|
-
* @param {Object} options - Render options
|
|
115
|
-
*/
|
|
116
|
-
addQRCodeToPDF(doc, data, x, y, options) {
|
|
117
|
-
// This is a simplified representation
|
|
118
|
-
// In a real implementation, you would use a QR code library
|
|
119
|
-
const size = 200;
|
|
120
|
-
const cellSize = 10;
|
|
121
|
-
const cells = size / cellSize;
|
|
122
|
-
|
|
123
|
-
// Draw QR code pattern
|
|
124
|
-
for (let row = 0; row < cells; row++) {
|
|
125
|
-
for (let col = 0; col < cells; col++) {
|
|
126
|
-
const shouldFill =
|
|
127
|
-
(data.charCodeAt((row * cells + col) % data.length) + row + col) %
|
|
128
|
-
2 ===
|
|
129
|
-
0;
|
|
130
|
-
|
|
131
|
-
if (shouldFill) {
|
|
132
|
-
doc.rect(x + col * cellSize, y + row * cellSize, cellSize, cellSize);
|
|
133
|
-
doc.fillColor(options.lineColor);
|
|
134
|
-
doc.fill();
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Add linear barcode to PDF
|
|
142
|
-
* @param {PDFDocument} doc - PDF document
|
|
143
|
-
* @param {string} data - The data to encode
|
|
144
|
-
* @param {string} type - The barcode type
|
|
145
|
-
* @param {number} x - X position
|
|
146
|
-
* @param {number} y - Y position
|
|
147
|
-
* @param {Object} options - Render options
|
|
148
|
-
*/
|
|
149
|
-
addLinearBarcodeToPDF(doc, data, type, x, y, options) {
|
|
150
|
-
const barWidth = options.width || 2;
|
|
151
|
-
let currentX = x;
|
|
152
|
-
|
|
153
|
-
// Draw bars based on data
|
|
154
|
-
for (let i = 0; i < data.length; i++) {
|
|
155
|
-
const char = data.charCodeAt(i);
|
|
156
|
-
const barCount = (char % 5) + 1;
|
|
157
|
-
|
|
158
|
-
for (let j = 0; j < barCount; j++) {
|
|
159
|
-
doc.rect(currentX, y, barWidth, options.height);
|
|
160
|
-
doc.fillColor(options.lineColor);
|
|
161
|
-
doc.fill();
|
|
162
|
-
currentX += barWidth * 2;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Get default options
|
|
169
|
-
* @returns {Object} Default options
|
|
170
|
-
*/
|
|
171
|
-
getDefaultOptions() {
|
|
172
|
-
return { ...this.defaultOptions };
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Set default options
|
|
177
|
-
* @param {Object} options - New default options
|
|
178
|
-
*/
|
|
179
|
-
setDefaultOptions(options) {
|
|
180
|
-
this.defaultOptions = { ...this.defaultOptions, ...options };
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
module.exports = PDFRenderer;
|
|
1
|
+
/**
|
|
2
|
+
* PDF Renderer - Renders barcodes as PDF
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const PDFDocument = require('pdfkit');
|
|
6
|
+
|
|
7
|
+
class PDFRenderer {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.defaultOptions = {
|
|
10
|
+
width: 2,
|
|
11
|
+
height: 100,
|
|
12
|
+
displayValue: true,
|
|
13
|
+
fontSize: 20,
|
|
14
|
+
textAlign: 'center',
|
|
15
|
+
textPosition: 'bottom',
|
|
16
|
+
textMargin: 2,
|
|
17
|
+
background: '#ffffff',
|
|
18
|
+
lineColor: '#000000',
|
|
19
|
+
margin: 10,
|
|
20
|
+
marginTop: 10,
|
|
21
|
+
marginBottom: 10,
|
|
22
|
+
marginLeft: 10,
|
|
23
|
+
marginRight: 10,
|
|
24
|
+
pageWidth: 612,
|
|
25
|
+
pageHeight: 792,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Render a barcode as PDF
|
|
31
|
+
* @param {string} data - The data to encode
|
|
32
|
+
* @param {string} type - The barcode type
|
|
33
|
+
* @param {Object} options - Render options
|
|
34
|
+
* @returns {Buffer} PDF buffer
|
|
35
|
+
*/
|
|
36
|
+
render(data, type, options = {}) {
|
|
37
|
+
try {
|
|
38
|
+
// Merge options with defaults
|
|
39
|
+
const renderOptions = { ...this.defaultOptions, ...options };
|
|
40
|
+
|
|
41
|
+
// Create PDF document
|
|
42
|
+
const doc = new PDFDocument({
|
|
43
|
+
size: [renderOptions.pageWidth, renderOptions.pageHeight],
|
|
44
|
+
margins: {
|
|
45
|
+
top: renderOptions.marginTop,
|
|
46
|
+
bottom: renderOptions.marginBottom,
|
|
47
|
+
left: renderOptions.marginLeft,
|
|
48
|
+
right: renderOptions.marginRight,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Collect PDF data
|
|
53
|
+
const chunks = [];
|
|
54
|
+
doc.on('data', chunk => chunks.push(chunk));
|
|
55
|
+
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
doc.on('end', () => {
|
|
58
|
+
const pdfBuffer = Buffer.concat(chunks);
|
|
59
|
+
resolve(pdfBuffer);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
doc.on('error', reject);
|
|
63
|
+
|
|
64
|
+
// Add barcode to PDF
|
|
65
|
+
this.addBarcodeToPDF(doc, data, type, renderOptions);
|
|
66
|
+
|
|
67
|
+
// Finalize PDF
|
|
68
|
+
doc.end();
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new Error(`PDF rendering failed: ${error.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Add barcode to PDF document
|
|
77
|
+
* @param {PDFDocument} doc - PDF document
|
|
78
|
+
* @param {string} data - The data to encode
|
|
79
|
+
* @param {string} type - The barcode type
|
|
80
|
+
* @param {Object} options - Render options
|
|
81
|
+
*/
|
|
82
|
+
addBarcodeToPDF(doc, data, type, options) {
|
|
83
|
+
// Set background color
|
|
84
|
+
doc.rect(0, 0, options.pageWidth, options.pageHeight);
|
|
85
|
+
doc.fillColor(options.background);
|
|
86
|
+
doc.fill();
|
|
87
|
+
|
|
88
|
+
// Calculate position
|
|
89
|
+
const x = options.marginLeft;
|
|
90
|
+
const y = options.marginTop;
|
|
91
|
+
|
|
92
|
+
if (type === 'qrcode') {
|
|
93
|
+
this.addQRCodeToPDF(doc, data, x, y, options);
|
|
94
|
+
} else {
|
|
95
|
+
this.addLinearBarcodeToPDF(doc, data, type, x, y, options);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Add text if displayValue is true
|
|
99
|
+
if (options.displayValue) {
|
|
100
|
+
doc.fontSize(options.fontSize);
|
|
101
|
+
doc.fillColor(options.lineColor);
|
|
102
|
+
doc.text(data, x, y + options.height + options.textMargin, {
|
|
103
|
+
align: options.textAlign,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Add QR Code to PDF
|
|
110
|
+
* @param {PDFDocument} doc - PDF document
|
|
111
|
+
* @param {string} data - The data to encode
|
|
112
|
+
* @param {number} x - X position
|
|
113
|
+
* @param {number} y - Y position
|
|
114
|
+
* @param {Object} options - Render options
|
|
115
|
+
*/
|
|
116
|
+
addQRCodeToPDF(doc, data, x, y, options) {
|
|
117
|
+
// This is a simplified representation
|
|
118
|
+
// In a real implementation, you would use a QR code library
|
|
119
|
+
const size = 200;
|
|
120
|
+
const cellSize = 10;
|
|
121
|
+
const cells = size / cellSize;
|
|
122
|
+
|
|
123
|
+
// Draw QR code pattern
|
|
124
|
+
for (let row = 0; row < cells; row++) {
|
|
125
|
+
for (let col = 0; col < cells; col++) {
|
|
126
|
+
const shouldFill =
|
|
127
|
+
(data.charCodeAt((row * cells + col) % data.length) + row + col) %
|
|
128
|
+
2 ===
|
|
129
|
+
0;
|
|
130
|
+
|
|
131
|
+
if (shouldFill) {
|
|
132
|
+
doc.rect(x + col * cellSize, y + row * cellSize, cellSize, cellSize);
|
|
133
|
+
doc.fillColor(options.lineColor);
|
|
134
|
+
doc.fill();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Add linear barcode to PDF
|
|
142
|
+
* @param {PDFDocument} doc - PDF document
|
|
143
|
+
* @param {string} data - The data to encode
|
|
144
|
+
* @param {string} type - The barcode type
|
|
145
|
+
* @param {number} x - X position
|
|
146
|
+
* @param {number} y - Y position
|
|
147
|
+
* @param {Object} options - Render options
|
|
148
|
+
*/
|
|
149
|
+
addLinearBarcodeToPDF(doc, data, type, x, y, options) {
|
|
150
|
+
const barWidth = options.width || 2;
|
|
151
|
+
let currentX = x;
|
|
152
|
+
|
|
153
|
+
// Draw bars based on data
|
|
154
|
+
for (let i = 0; i < data.length; i++) {
|
|
155
|
+
const char = data.charCodeAt(i);
|
|
156
|
+
const barCount = (char % 5) + 1;
|
|
157
|
+
|
|
158
|
+
for (let j = 0; j < barCount; j++) {
|
|
159
|
+
doc.rect(currentX, y, barWidth, options.height);
|
|
160
|
+
doc.fillColor(options.lineColor);
|
|
161
|
+
doc.fill();
|
|
162
|
+
currentX += barWidth * 2;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get default options
|
|
169
|
+
* @returns {Object} Default options
|
|
170
|
+
*/
|
|
171
|
+
getDefaultOptions() {
|
|
172
|
+
return { ...this.defaultOptions };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Set default options
|
|
177
|
+
* @param {Object} options - New default options
|
|
178
|
+
*/
|
|
179
|
+
setDefaultOptions(options) {
|
|
180
|
+
this.defaultOptions = { ...this.defaultOptions, ...options };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = PDFRenderer;
|
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PNG Renderer - Renders barcodes as PNG images
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { createCanvas } = require('canvas');
|
|
6
|
-
const JsBarcode = require('jsbarcode');
|
|
7
|
-
|
|
8
|
-
class PNGRenderer {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.defaultOptions = {
|
|
11
|
-
width: 2,
|
|
12
|
-
height: 100,
|
|
13
|
-
displayValue: true,
|
|
14
|
-
fontSize: 20,
|
|
15
|
-
textAlign: 'center',
|
|
16
|
-
textPosition: 'bottom',
|
|
17
|
-
textMargin: 2,
|
|
18
|
-
background: '#ffffff',
|
|
19
|
-
lineColor: '#000000',
|
|
20
|
-
margin: 10,
|
|
21
|
-
marginTop: 10,
|
|
22
|
-
marginBottom: 10,
|
|
23
|
-
marginLeft: 10,
|
|
24
|
-
marginRight: 10,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Render a barcode as PNG
|
|
30
|
-
* @param {string} data - The data to encode
|
|
31
|
-
* @param {string} type - The barcode type
|
|
32
|
-
* @param {Object} options - Render options
|
|
33
|
-
* @returns {Buffer} PNG buffer
|
|
34
|
-
*/
|
|
35
|
-
render(data, type, options = {}) {
|
|
36
|
-
try {
|
|
37
|
-
// Merge options with defaults
|
|
38
|
-
const renderOptions = { ...this.defaultOptions, ...options };
|
|
39
|
-
|
|
40
|
-
// Create canvas
|
|
41
|
-
const canvas = createCanvas(400, 200);
|
|
42
|
-
const ctx = canvas.getContext('2d');
|
|
43
|
-
|
|
44
|
-
// Set background
|
|
45
|
-
ctx.fillStyle = renderOptions.background;
|
|
46
|
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
47
|
-
|
|
48
|
-
// Generate barcode using JsBarcode
|
|
49
|
-
JsBarcode(canvas, data, {
|
|
50
|
-
format: this.mapBarcodeType(type),
|
|
51
|
-
width: renderOptions.width,
|
|
52
|
-
height: renderOptions.height,
|
|
53
|
-
displayValue: renderOptions.displayValue,
|
|
54
|
-
fontSize: renderOptions.fontSize,
|
|
55
|
-
textAlign: renderOptions.textAlign,
|
|
56
|
-
textPosition: renderOptions.textPosition,
|
|
57
|
-
textMargin: renderOptions.textMargin,
|
|
58
|
-
background: renderOptions.background,
|
|
59
|
-
lineColor: renderOptions.lineColor,
|
|
60
|
-
margin: renderOptions.margin,
|
|
61
|
-
marginTop: renderOptions.marginTop,
|
|
62
|
-
marginBottom: renderOptions.marginBottom,
|
|
63
|
-
marginLeft: renderOptions.marginLeft,
|
|
64
|
-
marginRight: renderOptions.marginRight,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Convert to PNG buffer
|
|
68
|
-
return canvas.toBuffer('image/png');
|
|
69
|
-
} catch (error) {
|
|
70
|
-
throw new Error(`PNG rendering failed: ${error.message}`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Map barcode type to JsBarcode format
|
|
76
|
-
* @param {string} type - The barcode type
|
|
77
|
-
* @returns {string} JsBarcode format
|
|
78
|
-
*/
|
|
79
|
-
mapBarcodeType(type) {
|
|
80
|
-
const typeMap = {
|
|
81
|
-
code128: 'CODE128',
|
|
82
|
-
code128a: 'CODE128A',
|
|
83
|
-
code128b: 'CODE128B',
|
|
84
|
-
code128c: 'CODE128C',
|
|
85
|
-
code128auto: 'CODE128',
|
|
86
|
-
code39: 'CODE39',
|
|
87
|
-
code39extended: 'CODE39',
|
|
88
|
-
code39checksum: 'CODE39',
|
|
89
|
-
code39auto: 'CODE39',
|
|
90
|
-
code93: 'CODE93',
|
|
91
|
-
ean13: 'EAN13',
|
|
92
|
-
ean8: 'EAN8',
|
|
93
|
-
upca: 'UPC',
|
|
94
|
-
upce: 'UPC',
|
|
95
|
-
codabar: 'codabar',
|
|
96
|
-
code11: 'CODE11',
|
|
97
|
-
msi: 'MSI',
|
|
98
|
-
pharmazentral: 'pharmazentral',
|
|
99
|
-
interleaved25: 'ITF',
|
|
100
|
-
standard25: 'STD25',
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
return typeMap[type] || 'CODE128';
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get default options
|
|
108
|
-
* @returns {Object} Default options
|
|
109
|
-
*/
|
|
110
|
-
getDefaultOptions() {
|
|
111
|
-
return { ...this.defaultOptions };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Set default options
|
|
116
|
-
* @param {Object} options - New default options
|
|
117
|
-
*/
|
|
118
|
-
setDefaultOptions(options) {
|
|
119
|
-
this.defaultOptions = { ...this.defaultOptions, ...options };
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
module.exports = PNGRenderer;
|
|
1
|
+
/**
|
|
2
|
+
* PNG Renderer - Renders barcodes as PNG images
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { createCanvas } = require('canvas');
|
|
6
|
+
const JsBarcode = require('jsbarcode');
|
|
7
|
+
|
|
8
|
+
class PNGRenderer {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.defaultOptions = {
|
|
11
|
+
width: 2,
|
|
12
|
+
height: 100,
|
|
13
|
+
displayValue: true,
|
|
14
|
+
fontSize: 20,
|
|
15
|
+
textAlign: 'center',
|
|
16
|
+
textPosition: 'bottom',
|
|
17
|
+
textMargin: 2,
|
|
18
|
+
background: '#ffffff',
|
|
19
|
+
lineColor: '#000000',
|
|
20
|
+
margin: 10,
|
|
21
|
+
marginTop: 10,
|
|
22
|
+
marginBottom: 10,
|
|
23
|
+
marginLeft: 10,
|
|
24
|
+
marginRight: 10,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Render a barcode as PNG
|
|
30
|
+
* @param {string} data - The data to encode
|
|
31
|
+
* @param {string} type - The barcode type
|
|
32
|
+
* @param {Object} options - Render options
|
|
33
|
+
* @returns {Buffer} PNG buffer
|
|
34
|
+
*/
|
|
35
|
+
render(data, type, options = {}) {
|
|
36
|
+
try {
|
|
37
|
+
// Merge options with defaults
|
|
38
|
+
const renderOptions = { ...this.defaultOptions, ...options };
|
|
39
|
+
|
|
40
|
+
// Create canvas
|
|
41
|
+
const canvas = createCanvas(400, 200);
|
|
42
|
+
const ctx = canvas.getContext('2d');
|
|
43
|
+
|
|
44
|
+
// Set background
|
|
45
|
+
ctx.fillStyle = renderOptions.background;
|
|
46
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
47
|
+
|
|
48
|
+
// Generate barcode using JsBarcode
|
|
49
|
+
JsBarcode(canvas, data, {
|
|
50
|
+
format: this.mapBarcodeType(type),
|
|
51
|
+
width: renderOptions.width,
|
|
52
|
+
height: renderOptions.height,
|
|
53
|
+
displayValue: renderOptions.displayValue,
|
|
54
|
+
fontSize: renderOptions.fontSize,
|
|
55
|
+
textAlign: renderOptions.textAlign,
|
|
56
|
+
textPosition: renderOptions.textPosition,
|
|
57
|
+
textMargin: renderOptions.textMargin,
|
|
58
|
+
background: renderOptions.background,
|
|
59
|
+
lineColor: renderOptions.lineColor,
|
|
60
|
+
margin: renderOptions.margin,
|
|
61
|
+
marginTop: renderOptions.marginTop,
|
|
62
|
+
marginBottom: renderOptions.marginBottom,
|
|
63
|
+
marginLeft: renderOptions.marginLeft,
|
|
64
|
+
marginRight: renderOptions.marginRight,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Convert to PNG buffer
|
|
68
|
+
return canvas.toBuffer('image/png');
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new Error(`PNG rendering failed: ${error.message}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Map barcode type to JsBarcode format
|
|
76
|
+
* @param {string} type - The barcode type
|
|
77
|
+
* @returns {string} JsBarcode format
|
|
78
|
+
*/
|
|
79
|
+
mapBarcodeType(type) {
|
|
80
|
+
const typeMap = {
|
|
81
|
+
code128: 'CODE128',
|
|
82
|
+
code128a: 'CODE128A',
|
|
83
|
+
code128b: 'CODE128B',
|
|
84
|
+
code128c: 'CODE128C',
|
|
85
|
+
code128auto: 'CODE128',
|
|
86
|
+
code39: 'CODE39',
|
|
87
|
+
code39extended: 'CODE39',
|
|
88
|
+
code39checksum: 'CODE39',
|
|
89
|
+
code39auto: 'CODE39',
|
|
90
|
+
code93: 'CODE93',
|
|
91
|
+
ean13: 'EAN13',
|
|
92
|
+
ean8: 'EAN8',
|
|
93
|
+
upca: 'UPC',
|
|
94
|
+
upce: 'UPC',
|
|
95
|
+
codabar: 'codabar',
|
|
96
|
+
code11: 'CODE11',
|
|
97
|
+
msi: 'MSI',
|
|
98
|
+
pharmazentral: 'pharmazentral',
|
|
99
|
+
interleaved25: 'ITF',
|
|
100
|
+
standard25: 'STD25',
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return typeMap[type] || 'CODE128';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get default options
|
|
108
|
+
* @returns {Object} Default options
|
|
109
|
+
*/
|
|
110
|
+
getDefaultOptions() {
|
|
111
|
+
return { ...this.defaultOptions };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Set default options
|
|
116
|
+
* @param {Object} options - New default options
|
|
117
|
+
*/
|
|
118
|
+
setDefaultOptions(options) {
|
|
119
|
+
this.defaultOptions = { ...this.defaultOptions, ...options };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = PNGRenderer;
|