将 PDF 文档打印到 esc/pos 热敏打印机
Printing PDF doc to esc/pos Thermal printer
我们正在使用 xamarin.forms 开发 POS 应用程序,因为我们需要将收据打印到通过 LAN 连接的 esc/pos 热敏打印机。
我们的应用程序支持多语言,通过更改代码页使用 esc/pos 命令打印多语言效果很好。
但它仅适用于某些受支持的语言,对于其他语言,它会打印垃圾字符(不可读的字符)。
所以我们考虑为收据创建一个 pdf 文件并打印该收据。我们尝试创建 pdf,然后转换为位图,然后使用 esc pos 命令发送到打印机,但它没有打印任何东西。
public BitImage(String filename)
{
Java.IO.File file = new Java.IO.File(filename);
var pdfRenderer = new PdfRenderer(ParcelFileDescriptor.Open(file, ParcelFileMode.ReadOnly));
PdfRenderer.Page page = pdfRenderer.OpenPage(0);
Bitmap bmp = Bitmap.CreateBitmap(page.Width, page.Height, Bitmap.Config.Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForPrint);
load(bmp);
}
private void load(Bitmap bmp)
{
int w = bmp.Width;
int h = bmp.Height;
int bw = (w + 7) / 8;
if (bw > 255)
bw = 255;
int bh = h / 8;
if (bh > 24)
{
bh = 24;
}
initData(bw * 8, bh * 8);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
if (bmp.GetPixel(x, y) == Color.Black)
setPixel(x, y);
}
}
}
private void initData(int w, int h)
{
width = w;
height = h;
pitch = h / 8;
data = new byte[w * pitch];
}
private void setPixel(int x, int y)
{
if (x >= width || y >= height)
{
return;
}
int mask = (0x0080 >> (y % 8));
data[(x * pitch) + (y / 8)] |= (byte)mask;
}
public void PrintData()
{
byte[] CMD_INIT = { 0x1B, 0x40 };
byte[] CMD_UPLOAD_IMAGE = { 0x1D, 0x2A, 0, 0 };
byte[] CMD_PRINT_IMAGE = { 0x1D, 0x2F, 0 };
byte[] CMD_CUT = { 0x1D, 0x56, 0x01 };
CMD_UPLOAD_IMAGE[2] = (byte)(width / 8);
CMD_UPLOAD_IMAGE[3] = (byte)(height / 8);
#region Print Via Lan
Socket pSocket = new Socket(SocketType.Stream, ProtocolType.IP);
pSocket.SendTimeout = 1500;
pSocket.Connect("192.168.15.168", 9100);
pSocket.Send(CMD_INIT);
pSocket.Send(CMD_UPLOAD_IMAGE);
pSocket.Send(data);
pSocket.Send(CMD_PRINT_IMAGE);
pSocket.Send(CMD_CUT);
pSocket.Close();
#endregion
}
请帮帮我,我的做法是否正确?
还是有更好的方法来做到这一点?
您可以使用 SkiaSharp 等库以任何语言从您的数据中制作 Image/PDF 并使用任何打印机正确打印它们。
我创建了一个示例来演示如何在 C# 中使用 ESC\POS 打印机正确打印图像:GitHub code repo
我们正在使用 xamarin.forms 开发 POS 应用程序,因为我们需要将收据打印到通过 LAN 连接的 esc/pos 热敏打印机。 我们的应用程序支持多语言,通过更改代码页使用 esc/pos 命令打印多语言效果很好。 但它仅适用于某些受支持的语言,对于其他语言,它会打印垃圾字符(不可读的字符)。
所以我们考虑为收据创建一个 pdf 文件并打印该收据。我们尝试创建 pdf,然后转换为位图,然后使用 esc pos 命令发送到打印机,但它没有打印任何东西。
public BitImage(String filename)
{
Java.IO.File file = new Java.IO.File(filename);
var pdfRenderer = new PdfRenderer(ParcelFileDescriptor.Open(file, ParcelFileMode.ReadOnly));
PdfRenderer.Page page = pdfRenderer.OpenPage(0);
Bitmap bmp = Bitmap.CreateBitmap(page.Width, page.Height, Bitmap.Config.Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForPrint);
load(bmp);
}
private void load(Bitmap bmp)
{
int w = bmp.Width;
int h = bmp.Height;
int bw = (w + 7) / 8;
if (bw > 255)
bw = 255;
int bh = h / 8;
if (bh > 24)
{
bh = 24;
}
initData(bw * 8, bh * 8);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
if (bmp.GetPixel(x, y) == Color.Black)
setPixel(x, y);
}
}
}
private void initData(int w, int h)
{
width = w;
height = h;
pitch = h / 8;
data = new byte[w * pitch];
}
private void setPixel(int x, int y)
{
if (x >= width || y >= height)
{
return;
}
int mask = (0x0080 >> (y % 8));
data[(x * pitch) + (y / 8)] |= (byte)mask;
}
public void PrintData()
{
byte[] CMD_INIT = { 0x1B, 0x40 };
byte[] CMD_UPLOAD_IMAGE = { 0x1D, 0x2A, 0, 0 };
byte[] CMD_PRINT_IMAGE = { 0x1D, 0x2F, 0 };
byte[] CMD_CUT = { 0x1D, 0x56, 0x01 };
CMD_UPLOAD_IMAGE[2] = (byte)(width / 8);
CMD_UPLOAD_IMAGE[3] = (byte)(height / 8);
#region Print Via Lan
Socket pSocket = new Socket(SocketType.Stream, ProtocolType.IP);
pSocket.SendTimeout = 1500;
pSocket.Connect("192.168.15.168", 9100);
pSocket.Send(CMD_INIT);
pSocket.Send(CMD_UPLOAD_IMAGE);
pSocket.Send(data);
pSocket.Send(CMD_PRINT_IMAGE);
pSocket.Send(CMD_CUT);
pSocket.Close();
#endregion
}
请帮帮我,我的做法是否正确? 还是有更好的方法来做到这一点?
您可以使用 SkiaSharp 等库以任何语言从您的数据中制作 Image/PDF 并使用任何打印机正确打印它们。
我创建了一个示例来演示如何在 C# 中使用 ESC\POS 打印机正确打印图像:GitHub code repo