Giter VIP home page Giter VIP logo

react-thermal-printer's Introduction

react-thermal-printer

npm version

React for thermal printing. It is used to print to a thermal printer that supports ESC/POS commands using React. It provides a custom renderer to convert React elements to Uint8Array, you can easily markup the printing stuffs using React components.

Installation

yarn

yarn add react-thermal-printer

pnpm

pnpm add react-thermal-printer

npm

npm install --save react-thermal-printer

Usage

import { Br, Cut, Line, Printer, Text, Row, render } from 'react-thermal-printer';

const receipt = (
  <Printer type="epson" width={42} characterSet="korea">
    <Text size={{ width: 2, height: 2 }}>9,500원</Text>
    <Text bold={true}>결제 완료</Text>
    <Br />
    <Line />
    <Row left="결제방법" right="체크카드" />
    <Row left="카드번호" right="123456**********" />
    <Row left="할부기간" right="일시불" />
    <Row left="결제금액" right="9,500" />
    <Row left="부가세액" right="863" />
    <Row left="공급가액" right="8,637" />
    <Line />
    <Row left="맛있는 옥수수수염차 X 2" right="11,000" />
    <Text>옵션1(500)/옵션2/메모</Text>
    <Row left="(-) 할인" right="- 500" />
    <Br />
    <Line />
    <Row left="합계" right="9,500" />
    <Row left="(-) 할인 2%" right="- 1,000" />
    <Line />
    <Row left="대표" right="김대표" />
    <Row left="사업자등록번호" right="000-00-00000" />
    <Row left="대표번호" right="0000-0000" />
    <Row left="주소" right="어디시 어디구 어디동 몇동몇호" />
    <Line />
    <Br />
    <Text align="center">Wifi: some-wifi / PW: 123123</Text>
    <Cut />
  </Printer>
);
const data: Uint8Array = await render(receipt);

receipt

API

Components

<Printer>

Interface of thermal printer.

Requires type to determine printer type.

<Printer type="epson">...</Printer>
<Printer type="epson" width={42}>...</Printer>
<Printer type="epson" characterSet="korea">...</Printer>

Note: Supported printer types are epson, star.

Custom encoder

Pass encoder prop to use custom encoder.

// utf8 encoding
const encoder = text => new TextEncoder().encode(text);
const receipt = (
  <Printer type="epson" encoder={encoder}>
    ...
  </Printer>
);

<Text>

Display text, and change text size or style to make it bold, underline, etc.

<Text> component also allows <div> element props.

<Text>text</Text>
<Text>fragment is {'allowed'}</Text>
<Text align="center">center text</Text>
<Text align="right">right text</Text>
<Text bold={true}>bold text</Text>
<Text underline="1dot-thick">underline text</Text>
<Text invert={true}>invert text</Text>
<Text size={{ width: 2, height: 2 }}>big size text</Text> 

Note: <Text> allows only text nodes.

<Row>

Display <Text> on the left and right sides.

<Row left="left" right="right" />
<Row left="left" right="right" gap={2} />
<Row 
  left={<Text>left</Text>}
  right="right"
/>
<Row
  left={<Text>left</Text>}
  right="very very long text will be multi line placed."
/>

<Br>

Feed line.

<Br />

<Line>

Draw line. Prints the character as much as the width which from <Printer>.

<Line />
<Line character="=" />

<Barcode>

Print barcode.

<Barcode type="UPC-A" content="111111111111" />
<Barcode type="CODE39" content="A000$" />
<Barcode align="center" type="UPC-A" content="111111111111" />

<QRCode>

Print qr code (2d barcode).

<QRCode content="https://github.com/seokju-na/react-thermal-printer" />
<QRCode align="center" content="https://github.com/seokju-na/react-thermal-printer" />

<Image>

Print image bitmap.

<Image src="https://my-cdn.com/image.png" />
<Image align="center" src="https://my-cdn.com/image.png" />
<Image src="https://my-cdn.com/image.png" reader={myCustomImageReader} />

function myCustomImageReader(
  elem: ReactElement<ComponentProps<typeof Image>>
): Promise<Image>;

Apply greyscale(Floyd-Steinberg dithering):

import { transforms } from '@react-therma-printer/image';

<Image src="https://my-cdn.com/image.png" transforms={[transforms.floydSteinberg]} />

<Cut>

Cut the paper.

Perform full/partial cutting, and feeds lines after cutting.

<Cut />
<Cut lineFeeds={6} />
// partial cut
<Cut partial={true} />

<Raw>

Print raw data.

<Raw data={Uint8Array.from([0x00, 0x01, ...])} />

<Cashdraw>

Open cash drawer.

<Cashdraw pin="2pin" />
<Cashdraw pin="5pin" />

Functions

render

Returns: Promise<Uint8Array>

Render element to Uint8Array data which corresponding to the esc/pos command.


Print via serial port (Web):

import { render, Printer, Text } from 'react-thermal-printer';

const data = await render(
  <Printer type="epson">
    <Text>Hello World</Text>
  </Printer>
);

const port = await window.navigator.serial.requestPort();
await port.open({ baudRate: 9600 });

const writer = port.writable?.getWriter();
if (writer != null) {
  await writer.write(data);
  writer.releaseLock();
}

Print via network (Nodejs):

import { render, Printer, Text } from 'react-thermal-printer';
import { connect } from 'node:net';

const data = await render(
  <Printer type="epson">
    <Text>Hello World</Text>
  </Printer>
);

const conn = connect({
  host: '192.168.0.99',
  port: 9100,
  timeout: 3000,
}, () => {
  conn.write(Buffer.from(data), () => {
    conn.destroy();
  });
});

License

MIT License

react-thermal-printer's People

Contributors

seokju-na avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-thermal-printer's Issues

Error Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')

Hey Guys, I do not have the printer yet, but I'm trying to test this library, I'm getting the follow error:

image

How can I solve this??

Packages:


"dependencies": {
    "@formatjs/intl-pluralrules": "4.3.3",
    "@formatjs/intl-relativetimeformat": "10.0.1",
    "@fortawesome/fontawesome-free": "6.1.1",
    "@hello-pangea/dnd": "^16.3.0",
    "@hotjar/browser": "^1.0.9",
    "@popperjs/core": "2.11.5",
    "@react-google-maps/api": "^2.19.0",
    "@storybook/react": "^7.3.2",
    "animate.css": "4.1.1",
    "apexcharts": "3.35.0",
    "axios": "0.26.1",
    "bootstrap": "5.2.2",
    "bootstrap-icons": "^1.5.0",
    "bootstrap-switch-button-react": "^1.2.0",
    "chart.js": "3.7.1",
    "clsx": "1.1.1",
    "formik": "2.2.9",
    "glamor": "^2.20.40",
    "i18next": "^23.4.6",
    "i18next-browser-languagedetector": "^7.1.0",
    "js-cookie": "^3.0.5",
    "laravel-echo": "^1.12.1",
    "line-awesome": "1.3.0",
    "lodash": "^4.17.21",
    "moment": "^2.29.4",
    "moment-timezone": "^0.5.43",
    "nouislider": "15.5.1",
    "polished": "^4.2.2",
    "prism-react-renderer": "1.3.1",
    "prism-themes": "1.9.0",
    "prismjs": "1.28.0",
    "pusher-js": "^7.2.0",
    "qs": "6.10.3",
    "react": "18.0.0",
    "react-apexcharts": "1.4.0",
    "react-app-alias": "^2.2.2",
    "react-app-rewired": "^2.2.1",
    "react-beautiful-dnd": "^12.1.0",
    "react-bootstrap": "2.5.0-beta.1",
    "react-copy-to-clipboard": "5.1.0",
    "react-dates": "^21.8.0",
    "react-dom": "18.0.0",
    "react-hook-form": "^7.45.0",
    "react-i18next": "^13.2.1",
    "react-if": "^4.1.5",
    "react-inlinesvg": "3.0.0",
    "react-input-mask": "3.0.0-alpha.2",
    "react-intl": "5.25.0",
    "react-number-format": "^4.9.3",
    "react-qr-code": "^2.0.12",
    "react-query": "3.38.0",
    "react-router-dom": "6.3.0",
    "react-scripts": "5.0.1",
    "react-svg": "^16.1.22",
    "react-table": "^7.7.0",
    "react-thermal-printer": "^0.17.0",
    "react-to-print": "^2.14.13",
    "react-toastify": "^9.1.3",
    "react-topbar-progress-indicator": "4.1.1",
    "sass": "^1.66.1",
    "socicon": "3.0.5",
    "yup": "0.32.11"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "5.16.4",
    "@testing-library/react": "13.1.1",
    "@testing-library/user-event": "13.5.0",
    "@types/bootstrap": "5.1.10",
    "@types/chart.js": "2.9.37",
    "@types/jest": "27.4.1",
    "@types/node": "16.11.27",
    "@types/prismjs": "1.26.0",
    "@types/qs": "6.9.7",
    "@types/react": "18.0.6",
    "@types/react-beautiful-dnd": "^13.1.4",
    "@types/react-copy-to-clipboard": "5.0.2",
    "@types/react-dates": "^21.8.3",
    "@types/react-dom": "18.0.2",
    "@types/react-input-mask": "^3.0.2",
    "@types/react-table": "^7.7.9",
    "@types/sass-loader": "8.0.3",
    "@vitejs/plugin-react": "^4.0.4",
    "@vitejs/plugin-react-refresh": "^1.3.6",
    "css-loader": "6.7.1",
    "del": "6.0.0",
    "mini-css-extract-plugin": "2.6.1",
    "prettier": "2.6.2",
    "rtlcss-webpack-plugin": "4.0.7",
    "sass-loader": "13.0.2",
    "typescript": "4.6.3",
    "vite": "^4.4.9",
    "webpack": "5.74.0",
    "webpack-cli": "4.10.0"
  },

Issue with using react-thermal-printer with local IP printers

Issue Description

(im using nextjs 14) I'm trying to work with local IP printers, specifically ECS/POS printers, using the react-thermal-printer library. Following the provided example code:

import { render, Printer, Text, Cut } from 'react-thermal-printer';
import { connect } from 'node:net';

const data = await render(
  <Printer type="epson" width={42}>
    <Text>Hello World</Text>
    <Cut />
  </Printer>
);

const conn = connect({
  host: '192.168.0.99',
  port: 9100,
  timeout: 3_000,
});
conn.write(Buffer.from(data), () => {
  conn.destroy();
});
conn.on('error', ...);
conn.on('timeout', ...);

However, when running this code in my Node.js environment (v21.6.1), I encounter the following error:

SyntaxError: Unexpected token '<'
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:168:18)
    at callTranslator (node:internal/modules/esm/loader:279:14)
    at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:285:30)
    at async link (node:internal/modules/esm/module_job:76:21)

It seems like there's an issue with the syntax when using JSX within a Node.js environment.

Request for Assistance

I'm unsure if I'm using the library incorrectly or if there's a compatibility issue with my setup. Any assistance or guidance on how to properly utilize react-thermal-printer with local IP printers would be greatly appreciated. I'm currently working on a personal project where this functionality is crucial.

Thank you for your time and assistance.

react/jsx-runtime not found

This dependency was not found:

  • react/jsx-runtime in ./node_modules/react-thermal-printer/esm/index.js

To install it, you can run: npm install --save react/jsx-runtime

Print via serial port (Web) - How to troubleshoot

Hello,

I am trying to use to connect website for receipt printing. Request prompt is coming to select available port for the printer but nothing is happening after connect.

I can see that data array being passed to Writer instance in debugging mode. Any help to how to get this working.

My code is executing this in a callback function on click event.

const data = await render(
  <Printer type="epson">
    <Text>Hello World</Text>
  </Printer>
);

const port = await window.navigator.serial.requestPort();
await port.open({ baudRate: 9600 });

const writer = port.writable?.getWriter();
if (writer != null) {
  await writer.write(data);
  writer.releaseLock();
}

Thanks,

GJ

Partial Cut Discussion

We have an issue where the paper is falling to the floor after a . It would be nice to be able to specify a partial cut. Either as a prop on the Cut component or a new component CutPartial. This could be implemented by adjusting the m parameter on the printer.cut() call. Maybe allowing the m parameter to be passed as a parameter from the Cut component. Thoughts?

Fix Module "stream" has been externalized for browser compatibility. Cannot access "stream.Transform" in client code.

const Render = (
  <Printer type='epson' width={42} characterSet='korea'>
    <Text size={{ width: 2, height: 2 }}>9,500원</Text>
    <Text bold={true}>결제 완료</Text>
    <Br />
    <Line />
    <Row left='결제방법' right='체크카드' />
    <Row left='카드번호' right='123456**********' />
    <Row left='할부기간' right='일시불' />
    <Br />
    <Text align='center'>Wifi: some-wifi / PW: 123123</Text>
    <Cut />
  </Printer>
);
function Invoice({ setPopup }: InvoiceProps) {
  const { state } = useContext(StoreContext);
  const { transaction, setTransaction } = useContext(OverlayContext);

  if (!transaction) setPopup(undefined);

  return (
    <Box
      position='absolute'
      right={0}
      top={0}
      w='350px'
      bg='bg'
      boxShadow='xl'
      px={4}
      py={6}
      h='100vh'
      maxH='100vh'
      borderLeftWidth={1}
      borderLeftColor='grey.300'
      zIndex={10}
    >
      <HStack
        // px={4}
        justify='space-between'
        w='100%'
        position='absolute'
        bottom={0}
      >
        <Button
          variant='secondary'
          onClick={() => {
            setTransaction(null);
            setPopup(undefined);
          }}
        >
          Back
        </Button>
        <HStack gap={4}>
          <Button
            onClick={async () => {
             //where am calling the print function
              const port = (await navigator.serial.requestPort());
              await port.open({ baudRate: 9600 });

              const writer = port.writable?.getWriter();
              if (writer != null) {
                await writer.write(Render);
                writer.releaseLock();
              }
            }}
            variant='secondary'
            leftIcon={<IoPrint fontSize='1rem' />}
          >
            Print
          </Button>
          <Button leftIcon={<IoShareSocialSharp />}>Share</Button>
        </HStack>
      </HStack>
    </Box>
  );
}

Am getting Module "stream" has been externalized for browser compatibility. Cannot access "stream.Transform" in client code.anytime I start the app which would literally crash the app.
Am I doing something wrong? Please help

Just pointing out an alternative method

First, thank for your incredible work ⭐

I could keep this myself without bothering you. But seeing #64 and many others, I thought I could just open this issue.

I made a fork: https://github.com/vajahath/image-thermal-printer

What it basically does is convert the "thing to print" into an image (or HTMLCanvasElemet) and use the https://github.com/seokju-na/react-thermal-printer/blob/main/packages/printer/src/commands/image.ts image command on it.

So far, it is working nice-ish (some tweaks needed here and there)

I converted my div into canvas (https://www.npmjs.com/package/html-to-image#toCanvas). Then printed it using the above command. This gave me unlimited customization.

(the printer I'm using is very old and of low quality - hence some lines segments are lost)
PXL_20240224_181001863 MP

Because the printers are generally having low resolution, serif typeface may not be a good choice. I prefer sans serif typeface. Roboto is a good choice. (Noto as well). Any font that claims to work well in low-res could be a good choice.

Some advantages I found:

  • Alignment: This is a solved problem in html. With now we having the container-queries, we can design a div the way we want.
  • Tables: html tables adjust themselves
  • Responsive: Thermal printer comes in many width - 2 inch (my case), 3 inch. With the right css you can target any number of widths.
  • Tiny and simplified code (mainly image manipulation is only required)
  • Framework agnostic.

Cons:

  • Need to fiddle around the printer dpi (mine is 200) and possible print widths.

This issue was to inform you an alternative method. Feel free to close this issue whenever you wish.

Printer Paper Width.

I am using this package for multiple printers with different printer paper while using the same system.

My question is the printer width in mm or in pixels. also if I don't set the width will it automatically determine the paper width itself.

@seokju-na please respond to this, it's urgent.

Thanks

render is not a function

I am using react-thermal-printer version ^0.11.0 in my React app. When I use the render function I get render is not a function
in console.

Are supported printer types Epson and Star only?

I saw this line in the documentation. Note: Supported printer types are epson, star.

Does this mean only printers from these two manufactures are supported? I was under the impression any printer with ESC/POS capability is supported. I did see in the JS conf video that the printer used was of neither company.

Also wondering what ports are best supported by this library? LAN WLAN USB

Disable floyd-steinberg option for print image

Is it posible to disable floyd-steinberg method for printing image?

  • current I'm using this library to print the whole receipt because mot of printer does not support Khmer Unicode.
  • so printing result with text image is not smooth

Some values are missing

in most of the printer it's worked fine, but when i tried to use printer model : KS-NET KS9050, some values are missing. do u know why?

안녕하세요 석주님! 써멀 프린트로 연결되어 있지 않았을 경우 PDF로 출력할 수 있을까요?

안녕하세요 석주님 우선 오픈 소스라이브러리에 기여해주셔서 감사합니다! 공교롭게 이번주에 써멀 프린터로 출력할 수 있도록 기능 구현해달라는 요청을 받았는데요, 덕분에 수월하게 진행 중에 있습니다.

석주님의 영상상자료와 리드미를 바탕으로 리액트 컴포넌트를 만들어서 아래와 같이 렌더링하려고 하고 있습니다.

Screen Shot 2022-12-23 at 1 27 12 PM

온클릭 함수로 프린트 함수를 전달해서 실행되도록 하단의 이미지 처럼 놓았구요.
Screen Shot 2022-12-23 at 1 27 21 PM

하지만, 아직 프린터를 회사로부터 수령받지 못해서 버튼을 클릭하면 다음과 같은 에러 메시지가 나타나더라구요.
Screen Shot 2022-12-23 at 1 34 41 PM

함수가 제대로 동작하는지 확인하고 싶은데, 혹시 PDF로 익스포트할 수 있도록 라이브러리에서 세팅하는 방법이 있을까요?
더불어서, 제가 석주님의 라이브러리를 제대로 적용했는지도 궁금합니다.

Can you extract the core (non-react) part of this module and publish as a separate package?

Great work!
Can you extract the core (non-react) part of this module and publish as a separate package?
You can reuse that core package in the react-thermal-printer module as well.

Motive:
I was searching for a thermal printer implementation to play around with pure JS and once settled, use it in Angular. So If you could extract out the core (non-react) part and publish as a new standalone package, that would be very helpful for the community.

Unable to connect printer using usb or serial requestPort

Unable to connect and print the text using usb cable and also get error :

DOMException: Failed to execute 'open' on 'SerialPort': Failed to open serial port. : (this in chrome)

TypeError: Cannot read properties of undefined (reading 'requestPort')
at handle (App.js:20:1) : (this in brave browser)

is it automatic connect to the printer or somthing else can you tellme how should i fixed it

import "./App.css";
import "leaflet/dist/leaflet.css";
import "leaflet-draw/dist/leaflet.draw.css";
import { Printer, Text, render } from "react-thermal-printer";


function App() {
  const handle = async() => {
    try {
      const data = await render(
        <Printer type="epson">
          <Text>Hello World</Text>
        </Printer>
      );
      
      const port = await window.navigator.serial.requestPort();
      await port.open({ baudRate: 9600 });
      
      const writer = port.writable?.getWriter();
      if (writer != null) {
        await writer.write(data);
        writer.releaseLock();
      }
      
     console.log('ehy', data, port)
    } catch (error) {
      console.log(error)
    }
  }

  return (
    <div className="App">
      <button onClick={handle}>Print</button>
    </div>
  );
}

export default App;

Printing in arabic is not working.

I'm trying to print Arabic text on a POS printer.
i have tried both "star" and "Epson" types
and i have tested on both wpc1256_arabic and pc864_arabic .

Printing in English is working fine. printing images using <Image src.. /> also works fine.
but when I try to print an Arabic text, it shows an unknown character. (not ???)

Printer function:

  const printer = async () => {
 
    if (!printerState) {
     // connecting to printer
       ....
           setPrinterState(() => characteristic);
       ....
    }

    printing();
  };

Printing function

  const printing = async () => {
    const data = await render(
      <Printer type="star" width={88} characterSet="wpc1256_arabic">
        <Text>مرحبا بك في رياكت</Text>
      </Printer>
    );
    // Print the data in chunks
    await printChunks(printerState, data);
  };
printChunks function:
  const sendChunk = async (printerState, chunk) => {
    try {
      await printerState.writeValueWithResponse(chunk);
    } catch (error) {
      console.error(`Error sending data chunk: ${error}`);
      throw error;
    }
  };
Printer trigger:
  <Button type="primary" onClick={printer}>
        PRINT
  </Button>

Row throws an error when string from right side is too big

The row component throws an error if the string length from right side is too big

example:

<Row
        left={<Text>CEP:</Text>}
        right={
          <Text>Antiga 18 portão de garagem vermelho casa de esquina</Text>
        }
/>

Error thrown:
Possible Unhandled Promise Rejection (id: 2):

RangeError: String.prototype.repeat count must be finite and non-negative
RangeError: String.prototype.repeat count must be finite and non-negative

Print Image Not working

how to print with image logo? can explain it?

when print with image my printer always print random black .

EPSON TM-T82X USB

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.