【问题标题】:How to generate tables rows dynamically in Nodejs using ESCPOS API module如何使用 ESCPOS API 模块在 Nodejs 中动态生成表行
【发布时间】:2021-01-18 00:21:28
【问题描述】:

几天前,我一直在努力使用 ESCPOS Java API 打印收据,但失败了,因为我找不到足够简单的 USB API 来允许程序使用 USB 接口打印到我的热敏打印机。后来我决定在 Node 和 ESCPOS 模块中实现这个。

我正在将此应用程序连接到 MySQL 数据库,以便能够从记录的交易中打印收据。我正在使用表格来创建产品列表及其各自的价格,但只能通过硬编码。我现在的问题是如何动态创建这些表。根据交易中涉及的产品,我希望脚本仅查询和打印这些产品。

这是收据代码!

const db = require('./database.js');
const escpos = require('escpos');
const uniqueRandom = require('unique-random');
const random = uniqueRandom(1000, 9999);


const device  = new escpos.USB();

const options = { encoding: "GB18030" }

exports.printGeneralReceipt = function(status){
  db.getTransactionDetails(function(res){
    data = res;
  }); 

  const printer = new escpos.Printer(device, options);
  console.log("Printer found!");

  device.open(function(){
    console.log("Receipt generating...");
    printer
    .font('b')
    .align('ct')
    .style('bu')
    .size(1, 1)
    .encode('utf8')
    .text('\n*****START OF LEGAL RECEIPT*****'+
    '\n\nCOMPUTICKET MALAWI\n'+
    'SHOP 31A, GAME COMPLEX\n'+
    'LILONGWE MALL\n\nwww.computicket.mw\n+265 (0) 99 974 7576\n')
    .table(["BUYER NAME :", "CLIFFORD MWALE", ""])
    .table(["RECEIPT # :", random(), ""])
    .table(["DATE: ", "12/AUG/2019", ""])
    .text("----------ITEM LIST----------\n")

    // ITEM LIST STARTS HERE
    .table(["MILK","$2"])
    .table(["PEANUT BUTTER", "$6"])
    // ITEM LIST ENDS HERE

    .text("--------------------------------")
    .table(["TOTAL PRICE", "$8.00", ""])
    .text("Operator: Jon Doe\n-------------------------------\n")
    .barcode('123456789012')
    .text("\n\nTHANK YOU\n\n*****END OF LEGAL RECEIPT*****")
    .beep(1,100)
  .cut().close();
  console.log("Receipt printed!");
});

}

这里是从数据库中提取交易细节的函数。我将免除您创建连接的开销。


exports.getTransactionDetails = function(trans_id){
    var res = "";
    conn.query("SELECT * FROM transactions JOIN products_in_transaction WHERE transactions.trans_id = products_in_transaction.trans_id "+
        " transactions.trans_id = '"+trans_id+"'", 
        function (error, results, fields) {
       for(var i = 0; i < results.length; i++){
         // SOME OPERATION HERE
       }
      });
}

【问题讨论】:

    标签: node.js escpos


    【解决方案1】:

    我会发布一些我玩过的代码,它有效;你需要安装html-to-text

    const escpos = require('escpos');
    
        // Select the adapter based on your printer type
        const device  = new escpos.USB();
    
        const printer = new escpos.Printer(device);
    
    
        const cartItems = [
            {category: 'test', price: 80, quantityToSell: 2, title: 'Hosting'},
            {category: 'test1', price: 820, quantityToSell: 63, title: 'Mouse'},
            {category: 'test00', price: 60, quantityToSell: 20, title: 'Sale'},
            {category: 'dvhfgnfgjfjg', price: 20, quantityToSell: 8, title: 'Keyboards'},
            {category: 'dvhfgnfgjfjg', price: 10, quantityToSell: 4, title: 'Keyss'},
            {category: 'dvhfgnfgjfjg', price: 70, quantityToSell: 1, title: 'Test'},
            {category: 'dvhfgnfgjfjg', price: 500, quantityToSell: 12, title: 'Whale oil'},
            {category: 'dvhfgnfgjfjg', price: 560, quantityToSell: 22, title: 'Papers'},
        ]
    
        // get total per line items
        const totalPerItemList = (item) => {
    
            let totalPerItem = 0
    
            totalPerItem = item.quantityToSell * item.price
    
    
            return totalPerItem
        }
    
        // get the total price
        let total = 0;
        for (let cartItem of cartItems) {
            var unitSum  = cartItem.quantityToSell * cartItem.price
            total += unitSum
    
        }
    
        // Create our html template, could be an html file on it's own
        const TestTable = `
        <!doctype html>
        <html>
            <head>
                <meta charset="utf-8">
                <title>Testing Title for table</title>            
            </head>   
            <body>
                <div class="invoice-box">
                    <table class="receipt-table" cellpadding="0" cellspacing="0" border="0">
                        <thead>
                            <tr class="heading">
                                <th>Item</th>
                                <th>Quantity</th>
                                <th>Unit Price</th>
                                <th>Total</th>
                            </tr>
                        </thead>
                        <tbody>
                            ${cartItems.map(item =>
                                `
                                    <tr>
                                        <td>${item.title}</td>
                                        <td>${item.quantityToSell}</td>
                                        <td>${item.price}</td>
                                        <td>${totalPerItemList(item)}</td>
                                    </tr>
                                `
                            )}
                        </tbody>
                        <tfoot>
                            <tr>
                                <td>
                                    TOTAL:${total}
                                </td>
                            </tr>                                                   
                        </tfoot>
                </table>
                </div>            
            </body>     
        </html>
        `
    
    
        const htmlToText = require('html-to-text');
    
        const text = htmlToText.fromString(TestTable, {
            wordwrap: false,
            tables: ['.receipt-box', '.receipt-table']
        });
    
    
        device.open(function(err){
    
            printer
                .font('a')
                .align('ct')
                .style('bu')
                .size(1, 1)
                .text('Printing Tables Dynamically with epos')
                .text('||||||||||||||||||||||||||')
                .text(text)
                .text('||||||||||||||||||||||||')
                .text('========================')
                .cut()
                .close()
        });
    

    【讨论】:

      【解决方案2】:

      我发现最快的方法是做我自己的项目中所做的事情

      'use strict'
      
      import { app, protocol, BrowserWindow,ipcMain } from 'electron'
      import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
      import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
      const escpos = require('escpos');
      escpos.USB = require('escpos-usb');
      const isDevelopment = process.env.NODE_ENV !== 'production' 
      
      // Scheme must be registered before the app is ready
      protocol.registerSchemesAsPrivileged([
        { scheme: 'app', privileges: { secure: true, standard: true } }
      ])
      async function createWindow() {
        // Create the browser window.
        const win = new BrowserWindow({
          width: 800,
          height: 600,
          webPreferences: {
            // Use pluginOptions.nodeIntegration, leave this alone
            // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
            nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
          }
        })
        win.menuBarVisible = false;
        if (process.env.WEBPACK_DEV_SERVER_URL) {
          // Load the url of the dev server if in development mode
          await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
          if (!process.env.IS_TEST) win.webContents.openDevTools()
        } else {
          createProtocol('app')
          // Load the index.html when not in development
          win.loadURL('app://./index.html')
        }
      }
      
      // Quit when all windows are closed.
      app.on('window-all-closed', () => {
        // On macOS it is common for applications and their menu bar
        // to stay active until the user quits explicitly with Cmd + Q
        if (process.platform !== 'darwin') {
          app.quit()
        }
      })
      
      app.on('activate', () => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
      })
      
      // This method will be called when Electron has finished
      // initialization and is ready to create browser windows.
      // Some APIs can only be used after this event occurs.
      app.on('ready', async () => {
        if (isDevelopment && !process.env.IS_TEST) {
          // Install Vue Devtools
          try {
            await installExtension(VUEJS_DEVTOOLS)
          } catch (e) {
            console.error('Vue Devtools failed to install:', e.toString())
          }
        }
        createWindow()
      })
      
      // Exit cleanly on request from parent process in development mode.
      if (isDevelopment) {
        if (process.platform === 'win32') {
          process.on('message', (data) => {
            if (data === 'graceful-exit') {
              app.quit()
            }
          })
        } else {
          process.on('SIGTERM', () => {
            app.quit()
          })
        }
      }
      function print(load){
        var _message = '';
       device.open(function(){
             _message = 'done'
              printer
              .font('a')
              .align('ct')
              .style('bu')
              .size(0.05, 0.05)
              .text('Road House Magodo')
              .text('Magodo Shopping Arcade Ayodele \r\n Fanoki Magodo Phase I')
              .table(['item','qty','total'])
              load.load.forEach((element)=>{
                return printer.table(element)
              })
              printer.text(`Total:   ${load.total}`)
              if(load.change!='card'){
                printer.text(`Change:   ${load.change}`)
              }else{
                printer.text('Method: Card')
              }
              printer.newLine()
              printer.newLine()
              printer.cut()
      
              printer
              .font('a')
              .align('ct')
              .style('bu')
              .size(0.05, 0.05)
              .text('Road House Magodo')
              .text('Magodo Shopping Arcade Ayodele \r\n Fanoki Magodo Phase I')
              .table(['item','qty','total'])
              load.load.forEach((element)=>{
                return printer.table(element)
              })
              printer.text(`Total:   ${load.total}`)
              if(load.change!='card'){
                printer.text(`Change:   ${load.change}`)
              }else{
                printer.text('Method: Card')
              }
              printer.newLine()
              printer.newLine()
              printer.cut()
              printer
              .font('a')
              .align('ct')
              .style('bu')
              .size(0.05, 0.05)
              .text('Road House Magodo')
              .text('Magodo Shopping Arcade Ayodele \r\n Fanoki Magodo Phase I')
              .table(['item','qty','total'])
              load.load.forEach((element)=>{
                return printer.table(element)
              })
              printer.text(`Total:   ${load.total}`)
              if(load.change!='card'){
                printer.text(`Change:   ${load.change}`)
              }else{
                printer.text('Method: Card')
              }
              printer.newLine()
              printer.cut()
              printer.close()
            },error=>{
              if(error){
                console.log(error)
                _message = error+'error'
                return
                }
            })
            return _message
      }
      const device  = new escpos.USB();
      const printer = new escpos.Printer(device);
      ipcMain.on('print', (_,load) => {
        let _fish =()=>{ 
          return print(JSON.parse(load))
        }
        _.reply(_fish());
      })
      

      基本上是传递你的数组或对象并循环遍历它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-26
        • 1970-01-01
        • 1970-01-01
        • 2020-03-10
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多