-
Notifications
You must be signed in to change notification settings - Fork 2
printFile vs printRaw
Satyendra Singh edited this page Feb 10, 2026
·
1 revision
Understanding when to use jobs.printFile() vs jobs.printRaw() is crucial for successful printing. Using the wrong function is the #1 cause of printing problems.
| What are you printing? | Use this function | Why? |
|---|---|---|
| PDF files | printFile |
Needs document processing |
| Text files | printFile |
Needs formatting/encoding |
| Microsoft Office docs | printFile |
Complex document structure |
| Images (JPG, PNG) | printFile |
Needs image processing |
| Receipt commands | printRaw |
Direct printer control |
| Label printer commands | printRaw |
Bypass driver processing |
| Barcode data | printRaw |
Precision required |
| ESC/POS commands | printRaw |
Binary command streams |
printFile sends files to the printer through the document processing pipeline:
- File reading: Loads the specified file from disk
- Driver processing: Printer driver interprets the document
- Rendering: Converts to printer-specific format
- Spooling: Routes through print spooler
Documents that need interpretation:
- PDF files
- Text files (need encoding/font handling)
- Image files (need scaling/color conversion)
- PostScript files
Code example - PDF printing:
const { jobs } = require('@ssxv/node-printer');
// Print a PDF invoice
const job = await jobs.printFile({
printer: 'HP LaserJet Pro',
file: 'invoice.pdf',
copies: 1,
paperSize: 'A4',
orientation: 'portrait'
});Code example - Text file printing:
// Print a plain text report
const job = await jobs.printFile({
printer: 'Office Printer',
file: 'report.txt',
copies: 1,
font: 'Courier New',
fontSize: 12
});const options = {
// Standard print options
copies: 2,
paperSize: 'A4', // 'Letter', 'Legal', 'A4', etc.
orientation: 'portrait', // 'portrait' or 'landscape'
color: true, // true for color, false for grayscale
quality: 'normal', // 'draft', 'normal', 'high'
// Margins (units depend on driver)
margins: {
top: 1,
bottom: 1,
left: 1,
right: 1
},
// Advanced options (driver-dependent)
duplex: 'none', // 'none', 'horizontal', 'vertical'
paperSource: 'auto' // 'auto', 'manual', 'tray1', etc.
};
const job = await jobs.printFile({
printer: 'Printer Name',
file: 'document.pdf',
...options
});❌ Using printFile for receipt printers:
// Wrong - ESC/POS commands in a text file
await jobs.printFile({ printer: 'Star TSP143', file: 'receipt-commands.txt' });
// Result: Printer prints the command codes as text, not commands❌ Assuming all options work on all printers:
// Wrong - thermal printer doesn't support color
await jobs.printFile({ printer: 'Thermal Printer', file: 'receipt.pdf', color: true });
// Result: Option ignored or job failsprintRaw sends data directly to the printer, bypassing document processing:
- Direct transmission: Sends bytes exactly as provided
- No interpretation: Printer driver doesn't process the data
- Raw queue: Uses raw print queue (if supported)
- Immediate execution: Printer executes commands directly
Direct printer command streams:
- ESC/POS thermal printer commands
- ZPL label printer commands
- Custom printer languages
- Binary data streams
Code example - Receipt printer:
const { jobs } = require('@ssxv/node-printer');
// ESC/POS commands for a receipt
const receiptData = Buffer.concat([
Buffer.from([0x1B, 0x40]), // ESC @ - Initialize printer
Buffer.from('STORE RECEIPT\n'), // Header text
Buffer.from([0x1B, 0x45, 0x01]), // ESC E - Bold on
Buffer.from('Total: $25.99\n'), // Bold total
Buffer.from([0x1B, 0x45, 0x00]), // ESC E - Bold off
Buffer.from([0x1B, 0x64, 0x03]) // ESC d - Cut paper
]);
const job = await jobs.printRaw({
printer: 'Star TSP143',
data: receiptData,
type: 'RAW'
});Code example - Label printer:
// ZPL commands for a shipping label
const labelData = Buffer.from(`
^XA
^FO20,30^ADN,36,20^FDSHIP TO:^FS
^FO20,80^ADN,18,10^FDJohn Smith^FS
^FO20,110^ADN,18,10^FD123 Main St^FS
^FO20,140^ADN,18,10^FDAnytown, ST 12345^FS
^XZ
`);
const job = await jobs.printRaw({
printer: 'Zebra ZT220',
data: labelData,
type: 'RAW'
});const options = {
// Required for most raw printing
type: 'RAW', // Tells spooler to bypass processing
// Optional metadata
jobName: 'Receipt #123', // Job name in print queue
// Platform-specific options
priority: 'normal' // Job priority (if supported)
};
const job = await jobs.printRaw({
printer: 'Printer Name',
data: binaryData,
...options
});❌ Using printRaw for PDF files:
// Wrong - PDF needs document processing
const pdfData = fs.readFileSync('document.pdf');
await jobs.printRaw({ printer: 'HP LaserJet', data: pdfData });
// Result: Printer prints PDF bytes as text garbage❌ Forgetting the RAW type option:
// Wrong - missing type: 'RAW'
await jobs.printRaw({ printer: 'Receipt Printer', data: escposData });
// Result: Driver might try to process binary commands as text❌ Using wrong command format:
// Wrong - text commands for binary printer
const commands = Buffer.from('CUT PAPER\nPRINT RECEIPT');
await jobs.printRaw({ printer: 'Star TSP143', data: commands, type: 'RAW' });
// Result: Printer doesn't understand text commandsasync function printReceipt(order) {
// Build ESC/POS command sequence
const commands = [];
// Initialize and set character set
commands.push(Buffer.from([0x1B, 0x40])); // ESC @ - Initialize
commands.push(Buffer.from([0x1B, 0x74, 0x01])); // ESC t - Code page 437
// Header
commands.push(Buffer.from([0x1B, 0x61, 0x01])); // ESC a - Center align
commands.push(Buffer.from('RESTAURANT NAME\n'));
commands.push(Buffer.from([0x1B, 0x61, 0x00])); // ESC a - Left align
// Order items
for (const item of order.items) {
const line = `${item.name.padEnd(20)} $${item.price.toFixed(2)}\n`;
commands.push(Buffer.from(line));
}
// Total
commands.push(Buffer.from([0x1B, 0x45, 0x01])); // Bold on
const total = `TOTAL: $${order.total.toFixed(2)}\n`;
commands.push(Buffer.from(total));
// Cut paper
commands.push(Buffer.from([0x1B, 0x64, 0x05])); // Cut with 5 line feed
const receiptData = Buffer.concat(commands);
return await jobs.printRaw({ printer: 'Kitchen Printer', data: receiptData, type: 'RAW' });
}async function printInvoice(invoiceFile, customerCopies = 1, internalCopies = 1) {
const results = [];
// Customer copy - high quality
if (customerCopies > 0) {
const customerJob = await jobs.printFile({
printer: 'Customer Printer',
file: invoiceFile,
copies: customerCopies,
quality: 'high',
paperSize: 'Letter',
color: true
});
results.push({ type: 'customer', jobId: customerJob.id });
}
// Internal copy - draft quality
if (internalCopies > 0) {
const internalJob = await jobs.printFile({
printer: 'Office Printer',
file: invoiceFile,
copies: internalCopies,
quality: 'draft',
paperSize: 'Letter',
color: false // Save on color toner
});
results.push({ type: 'internal', jobId: internalJob.id });
}
return results;
}async function printShippingLabel(shipment) {
// Generate ZPL (Zebra Programming Language) commands
const zpl = `
^XA
^FO50,50^ADN,36,20^FD${shipment.carrier}^FS
^FO50,100^BY3^BCN,100,Y,N,N^FD${shipment.trackingNumber}^FS
^FO50,250^ADN,24,15^FDShip To:^FS
^FO50,290^ADN,18,12^FD${shipment.recipient.name}^FS
^FO50,320^ADN,18,12^FD${shipment.recipient.address1}^FS
^FO50,350^ADN,18,12^FD${shipment.recipient.city}, ${shipment.recipient.state} ${shipment.recipient.zip}^FS
^XZ
`.trim();
const labelData = Buffer.from(zpl);
const job = await jobs.printRaw({
printer: 'Zebra Label Printer',
data: labelData,
type: 'RAW',
jobName: `Label-${shipment.trackingNumber}`
});
return job.id;
}Are you printing a file that exists on disk?
├─ YES → Are you printing to a receipt/label printer?
│ ├─ YES → Is the file containing printer commands (not a document)?
│ │ ├─ YES → Use printRaw with file contents
│ │ └─ NO → Use printFile (but it might not work well)
│ └─ NO → Use printFile
│
└─ NO → Are you sending direct printer commands?
├─ YES → Use printRaw
└─ NO → Create a file first, then use printFile
-
RAW datatype required: Must specify
type: 'RAW' - Driver bypass: Completely skips Windows printer driver
- Binary safe: Handles all binary data correctly
- CUPS raw queue: Uses application/octet-stream MIME type
- PPD bypass: Ignores PostScript Printer Description processing
- Filter bypass: Skips CUPS filtering pipeline
- Job Lifecycle and States - Monitor your print jobs
- Platform Notes - Platform-specific considerations
- Printing Concepts - Understanding the printing fundamentals