Java如何轻松打印购物小票?

Java打印购物小票可通过控制台输出实现:使用System.out.printf()格式化输出商品名称、单价、数量和金额,创建商品对象列表,遍历计算总价,最后打印表头和汇总信息,关键点包括对齐列宽、保留小数位数和添加分隔线增强可读性。

Java打印购物小票是零售、餐饮等系统开发的常见需求,以下是三种实用方法,涵盖不同场景(控制台调试、物理打印机输出、PDF生成),均采用标准Java API或主流库实现,确保代码健壮性和可维护性。

Java如何轻松打印购物小票?


基础方案:控制台打印(调试用)

适用于开发阶段快速验证小票格式和逻辑。

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ConsoleReceiptPrinter {
    public static void main(String[] args) {
        // 模拟订单数据
        Map<String, Double> items = new HashMap<>();
        items.put("可口可乐", 3.50);
        items.put("薯片", 8.00);
        items.put("矿泉水", 2.00);
        printReceipt("C001", items, 0.9); // 9折优惠
    }
    public static void printReceipt(String orderId, Map<String, Double> items, double discount) {
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 小票头部
        sb.append("n============ 超市收银小票 ============n");
        sb.append("订单号: ").append(orderId).append("n");
        sb.append("时间: ").append(sdf.format(new Date())).append("n");
        sb.append("-----------------------------------n");
        // 商品列表
        double subtotal = 0;
        for (Map.Entry<String, Double> entry : items.entrySet()) {
            String itemName = entry.getKey();
            double price = entry.getValue();
            sb.append(String.format("%-10st¥%.2fn", itemName, price)); // 左对齐商品名
            subtotal += price;
        }
        // 费用计算
        double discountedAmount = subtotal * discount;
        double savings = subtotal - discountedAmount;
        sb.append("-----------------------------------n");
        sb.append(String.format("小计: tt¥%.2fn", subtotal));
        sb.append(String.format("折扣: tt%.0f折n", discount * 10));
        sb.append(String.format("优惠: tt¥%.2fn", savings));
        sb.append(String.format("总计: tt¥%.2fn", discountedAmount));
        sb.append("===================================n");
        sb.append("感谢惠顾!客服电话:400-123-4567n");
        System.out.println(sb.toString());
    }
}

输出效果:

============ 超市收银小票 ============
订单号: C001
时间: 2025-10-05 14:30:25
-----------------------------------
可口可乐      ¥3.50
薯片         ¥8.00
矿泉水       ¥2.00
-----------------------------------
小计:         ¥13.50
折扣:         9折
优惠:         ¥1.35
总计:         ¥12.15
===================================
感谢惠顾!客服电话:400-123-4567

实战方案:连接物理打印机

使用 javax.print API 直接驱动打印机(支持USB/网络打印机)。

import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
public class PhysicalPrinterService {
    public static void main(String[] args) {
        String receiptContent = generateReceiptContent(); // 生成小票文本
        try {
            // 1. 获取打印机服务
            PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
            if (printer == null) {
                throw new IllegalStateException("未找到默认打印机");
            }
            // 2. 设置打印参数
            PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
            attributes.add(new Copies(1)); // 打印份数
            // 3. 创建打印任务
            DocPrintJob job = printer.createPrintJob();
            Doc doc = new SimpleDoc(
                new ByteArrayInputStream(receiptContent.getBytes(StandardCharsets.UTF_8)),
                DocFlavor.INPUT_STREAM.AUTOSENSE,
                null
            );
            // 4. 执行打印
            job.print(doc, attributes);
            System.out.println("小票打印任务已发送");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static String generateReceiptContent() {
        // 复用控制台方案中的生成逻辑
        return new ConsoleReceiptPrinter().generateReceiptString();
    }
}

关键注意事项:

Java如何轻松打印购物小票?

  1. 中文乱码问题
    确保打印机支持UTF-8编码,热敏打印机通常需设置为中文字库模式(如ESC/POS指令集)。
  2. 打印机选择
    可通过 PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null); 列出所有打印机。
  3. 格式对齐
    使用制表符 t 或空格调整列宽,推荐固定宽度字体(如”Courier New”)。

扩展方案:生成PDF小票

使用 Apache PDFBox 库生成可保存/打印的PDF文件(需添加Maven依赖):

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.27</version>
</dependency>
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import java.io.IOException;
public class PdfReceiptGenerator {
    public static void main(String[] args) throws IOException {
        try (PDDocument document = new PDDocument()) {
            PDPage page = new PDPage();
            document.addPage(page);
            try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                contentStream.setFont(PDType1Font.COURIER_BOLD, 14);
                contentStream.beginText();
                contentStream.newLineAtOffset(50, 700); // 起始坐标
                // 逐行写入内容(实际项目可封装为方法)
                contentStream.showText("============ 超市电子小票 ============");
                contentStream.newLineAtOffset(0, -20); // 下移20像素
                contentStream.showText("订单号: PDF20251005001");
                // 更多行省略... 参考控制台方案的格式
                contentStream.endText();
            }
            document.save("receipt.pdf"); // 保存文件
            System.out.println("PDF小票已生成");
        }
    }
}

最佳实践与避坑指南

  1. 格式对齐

    • 使用 String.format() 控制列宽,
      String.format("%-20s %10.2f", productName, price)
      (左对齐商品名,右对齐价格)
  2. 字符编码

    • 物理打印时,若遇中文乱码:
      • 方案1:打印机切换至GBK/GB2312模式
      • 方案2:将文本转换为字节流时指定编码:
        receiptContent.getBytes("GB18030")
  3. 打印超时处理

    Java如何轻松打印购物小票?

    job.print(doc, attributes); // 默认可能阻塞
    // 建议改用异步线程,避免主线程卡死
  4. 商业系统推荐

    • 复杂场景(如POS机)使用 ESC/POS指令集 直接控制打印机(需厂商文档)
    • 开源库推荐:JavaPOSQZ Tray(支持网页调用打印机)

引用说明

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/28744.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年6月17日 22:56
下一篇 2025年6月17日 23:06

相关推荐

  • Java画笔如何加粗?

    在Java中,使用Graphics2D对象的setStroke方法,传入BasicStroke实例并指定宽度值即可加粗画笔,g2d.setStroke(new BasicStroke(5.0f))。

    2025年6月14日
    200
  • Java如何实现概率计算代码?

    在Java中实现概率功能,通常使用java.util.Random或Math.random()生成随机数,通过比较随机值与预设概率阈值决定事件触发,若事件概率为30%,则当随机数小于0.3时执行,也可结合区间划分处理多级概率场景。

    2025年6月11日
    100
  • Java如何高效存储数据?

    在Java中可通过变量存储基本数据,集合框架(如List/Map)管理对象组,数组存放同类型元素,文件/数据库持久化数据,或利用对象封装属性实现结构化存储。

    2025年6月2日
    300
  • Java如何快速导入库?

    在Java项目中导入外部库主要有三种方式:使用IDE(如IntelliJ/Eclipse)自动添加依赖;手动下载JAR文件并加入项目构建路径;或通过构建工具(如Maven/Gradle)在配置文件中声明依赖后自动下载管理,推荐使用Maven/Gradle简化流程。

    2025年6月11日
    200
  • JavaWeb开发怎么做?

    使用Java进行网页开发主要通过后端技术实现,如Servlet、JSP或Spring Boot框架处理HTTP请求和业务逻辑,结合HTML/CSS/JS前端构建页面,常用Tomcat等服务器部署运行。

    2025年6月13日
    100

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN