Make you own printer network with a simple software. Connect all your printers into one server
This project was made with the support of those packages:
- https://github.com/artiebits/pdf-to-printer Windows
- https://github.com/artiebits/unix-print Unix
- https://www.npmjs.com/package/zuzel-printer Support package
- https://github.com/marcbachmann/node-html-pdf PDF conversor
- https://github.com/song940/node-escpos Cash Drawer
This project create a Node server where any device can connect to the web server and print any Printer connected into the server.
Example schema:
Clone the project or download the last release compressed .rar
git clone https://github.com/ZhengLinLei/node-server-printer.git
Once you have downloaded the project, run the npm
install command:
# cd to the project and run this command
npm install
# NPM will download all the packages automatically
Now continue to configurate the project files and personal datas.
Open the project in your code editor and change some configuration.
Open the file ./config/server.js
and modify all the values with the correct situation:
const SERVER_CONFIG = {
"name": "node-server-printer",
// REPLACE TO YOUR DEFAULT PORT
"port": 3000, // Deploy port :80
"welcome-text": "Server on port: $port", // Variables: $port, $ip, $domain
// SERVER OS
"os": "win32" // Values ["win32", "unix"]
}
module.exports = SERVER_CONFIG;
Note: Please configurate correctly the OS value, or else the server will not work
The system will choose the default values, but you can change it with two ways:
To access you must go to 'server.domain/config' url or in '/' you can find an acnchor url where if you click it you will be redirected to settings page.
/*===============
./routes/index.js (7 - 26)
================*/
// Personalizate
router.get('/', (req, res) =>{
// Replace all here to your project main frontend files
res.render('index', {
title: "Welcome!"
})
});
/* ... */
// Module default
router.get('/config', async (req, res) =>{
// Get printer list to config
let def = await Controller.getPrinter(); // Get the Default Printer
let printers = await Controller.getPrinters(); // Get the list of Printers
res.render('config', {
def,
printers
});
});
Call the controller in ./controllers/controller.js
and call this function:
const Controller = require('./controllers/controller'); // Change the patyh according to your position
let param = 'printer'; // Read below to check the parameters accepted
let value = 'NAME_PRINTER';
Controller.setConfig(param, value);
Avaliables parameters:
printer
: [values] (str:name of the printer)
You can read the avaliables parameters in ./models/model.js
file with or calling it in Controller
object:
const Controller = require('./controllers/controller'); // Change the patyh according to your position
console.log(Controller.DATA_DEFAULT);
To get the list of the printers, click here
Run the project by calling the index.js
file with node
node index.js
# or
npm run start
or call it with Nodemon, so you can save the project and the server will update automatically
npm run dev
Once you have all, open http://localhost:3000
(change the port if you have changed in the server config file), if you can see the welcome page means you have executed the project succesfully. Continue reading to know the API functions
All functions can be modified and added in ./controllers/controller.js
and ./models/model.js
Call this function to clean the TMP folder:
// ./index.js (43 - 47)
app.listen(app.get('port'), ()=>{
Controller.cleanTMP_(); // Remove all temporal files
// Server activated
console.log(app.get('welcome-text'));
});
This function update the default options, please read Configuration for more information
Call this function to get the default printer
const Controller = require('./controllers/controller.js');
// Method 1:
(async function fnc(){
console.log(await Controller.getPrinter());
})();
// Method 2:
Controller.getPrinter().then(console.log);
// Output { deviceId: 'XP-80C', name: 'XP-80C' }
Same as getPrinter
, but in this case the function return the array of all printers
const Controller = require('./controllers/controller.js');
// Method 1:
(async function fnc(){
console.log(await Controller.getPrinters());
})();
// Method 2:
Controller.getPrinters().then(console.log);
// Output
// [
// { deviceId: 'XP-80C', name: 'XP-80C' },
// {
// deviceId: 'Microsoft XPS Document Writer',
// name: 'Microsoft XPS Document Writer'
// },
// {
// deviceId: 'Microsoft Print to PDF',
// name: 'Microsoft Print to PDF'
// },
// {
// deviceId: 'OneNote for Windows 10',
// name: 'OneNote for Windows 10'
// },
// { deviceId: 'Fax', name: 'Fax' }
// ]
To print any file, prepare the print options template
let option = {
printer: 'Zebra', //[can be declared in GET parameter, if you specify this option, the system will choose this option as first printer]
pages: "1-3,5", //[The number of page that the client want to print: syntax <num-num> will print the pages from "num" to "num", <num, num> will only print the "num" and "num" pages]
subset: "odd", //[Will print odd pages only when value is "odd". Will print even pages only when "even"]
scale: "fit",
copies: 1 //[Specifies how many copies will be printed]
//... [More options in https://github.com/artiebits/pdf-to-printer#printpdf-options--promisevoid]
}
And call it:
const Controller = require('./controllers/controller.js');
Controller.printFile('./tmp/file.pdf', {printer: "Fax"}, () =>{
console.log('Printed!!');
})
Note: All of those functions are for internal calling, for knowing the structure of the server and for helping you to undestand how to modify the source code and personalizate it to create your own version. If you are looking for server API to client print please continue reading
The query path is : server.domain/print/:type/:printer?
router.post('/print/:type/:printer?', async (req, res) =>{}); // ./routes/index.js (47 ~)
-
:type => Only
file
andhtml
argument can be accepted.- file: Upload any
pdf
,png
,jpg
file to print. POST method "file" - html: Upload
html
string to print. POST method "html"
- file: Upload any
You must specify the type, and in POST content include the data with the name of "file" or "html"
- :printer => Specify the printer name, optional parameter, if you leave it in blank the system will choose the default printer to print
-
[file] => FILE content, you must upload this content if you want to print
file
content and you have specified:type
as file in GET parameters -
[html] => If you choose in
:type
thehtml
option, you have to pass this POST content -
[pdfOptions>] => Additionally when you choose
html
type you have to pass the options to convert the HTML into PDF
// Example pdfOption
let config = {
// Export options
"directory": "/tmp", // The directory the file gets written into if not using .toFile(filename, callback). default: '/tmp'
// Papersize Options: http://phantomjs.org/api/webpage/property/paper-size.html
"height": "10.5in", // allowed units: mm, cm, in, px
"width": "8in", // allowed units: mm, cm, in, px
//- or -
"format": "Letter", // allowed units: A3, A4, A5, Legal, Letter, Tabloid
"orientation": "portrait", // portrait or landscape
// Page options
"border": "0", // default is 0, units: mm, cm, in, px
//- or -
"border": {
"top": "2in", // default is 0, units: mm, cm, in, px
"right": "1in",
"bottom": "2in",
"left": "1.5in"
},
"paginationOffset": 1, // Override the initial pagination number
"header": {
"height": "45mm",
"contents": '<div style="text-align: center;">Author: Marc Bachmann</div>'
},
"footer": {
"height": "28mm",
"contents": {
"first": 'Cover page',
2: 'Second page', // Any page number is working. 1-based index
"default": '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
"last": 'Last Page'
}
},
// Rendering options
"base": "file:///home/www/your-asset-path/", // Base path that's used to load files (images, css, js) when they aren't referenced using a host
// Zooming option, can be used to scale images if `options.type` is not pdf
"zoomFactor": "1", // default is 1
// File options
"type": "pdf", // allowed file types: png, jpeg, pdf
"quality": "75", // only used for types png & jpeg
// ... More information in: https://www.npmjs.com/package/html-pdf?activeTab=readme
}
- [printOption] => Parameter of the options to print, must be passed in every API call
// Example printOptions
let option = {
printer: 'Zebra', //[can be declared in GET parameter, if you specify this option, the system will choose this option as first printer]
pages: "1-3,5", //[The number of page that the client want to print: syntax <num-num> will print the pages from "num" to "num", <num, num> will only print the "num" and "num" pages]
subset: "odd", //[Will print odd pages only when value is "odd". Will print even pages only when "even"]
scale: "fit",
copies: 1 //[Specifies how many copies will be printed]
//... [More options in https://github.com/artiebits/pdf-to-printer#printpdf-options--promisevoid]
}
With file :type
fetch: localhost:3000/file/MyPrinter
GET
<body;
type = file;
printer? = MyPrinter;
>
POST
<body;
file = <file_data: filename.pdf>
printOptions = {
copies: 3
}
>
With html :type
fetch: localhost:3000/html
GET
<body;
type = file;
printer? = MyPrinter;
>
POST
<body;
html = <h1>Hello World!!</h1>
pdfOptions = {
format: "A4",
}
printOptions = {
printer: "MyPrinter"
copies: 3
}
>
The query path is : server.domain/openCashDrawer
in ``GET` method:
Example: JS
fetch('/openCashDrawer')
.then(response => response.json())
.then(data => console.log);
Configurate it in ./controllers/controllers.js [99-106]