Android Studio中实现Zebra打印机TXT布局变量打印的方案
Dataflex打印功能迁移至Android Java的实现思路
一、先优化模板占位符(核心简化点)
原Dataflex用下划线做占位符易混淆,建议先做调整:
- 若必须保留下划线规则:明确每个变量对应的下划线固定长度(比如10个下划线=客户名,8个=订单号),整理成映射表。
- 若可修改模板:把下划线替换为命名占位符(如
{{customerName}}),后续替换逻辑更直观,避免长度匹配错误。
二、模板读取与替换逻辑
情况1:固定长度下划线占位符
适合原系统严格按长度分配变量的场景,步骤如下:
- 一次性读取整个模板内容(比逐行逐字符处理高效)
- 定义变量映射,同时处理格式对齐(保持原打印布局)
- 按下划线长度从长到短替换(避免短长度先匹配导致长占位符失效)
示例代码:
import java.nio.file.Files; import java.nio.file.Paths; import java.nio.charset.StandardCharsets; import java.util.*; // 读取模板文件(注意编码和原Dataflex一致,比如GBK) String template = new String(Files.readAllBytes(Paths.get("打印模板.txt")), StandardCharsets.GBK); // 定义变量映射:key=下划线长度,value=格式化后的变量内容 Map<Integer, String> varMap = new HashMap<>(); varMap.put(10, String.format("%-10s", "张三")); // 左对齐,补空格至10位 varMap.put(8, String.format("%8s", "ORD202401")); // 右对齐,补空格至8位 varMap.put(12, String.format("%12.2f", 1234.56)); // 金额右对齐,保留2位小数 // 按长度倒序排序,优先替换长下划线 List<Integer> sortedLengths = new ArrayList<>(varMap.keySet()); Collections.sort(sortedLengths, Collections.reverseOrder()); for (int len : sortedLengths) { String placeholder = "_".repeat(len); template = template.replace(placeholder, varMap.get(len)); } // 传递给打印逻辑 sendToPrinter(template);
情况2:命名占位符
适合可修改模板的场景,替换逻辑更简洁:
// 读取模板文件 String template = new String(Files.readAllBytes(Paths.get("打印模板.txt")), StandardCharsets.GBK); // 定义变量键值对 Map<String, String> vars = new HashMap<>(); vars.put("customerName", "张三"); vars.put("orderNo", "ORD202401"); vars.put("amount", "1234.56"); // 批量替换占位符 for (Map.Entry<String, String> entry : vars.entrySet()) { template = template.replace("{{" + entry.getKey() + "}}", entry.getValue()); } sendToPrinter(template);
三、Android打印实现
Android中可通过PrintManager实现打印,示例代码如下:
import android.content.Context; import android.print.PrintAttributes; import android.print.PrintDocumentAdapter; import android.print.PrintDocumentInfo; import android.print.PrintManager; import android.os.ParcelFileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; private void sendToPrinter(String content) { PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE); String jobName = getString(R.string.app_name) + " 打印任务"; printManager.print(jobName, new PrintDocumentAdapter() { @Override public void onLayout(PrintAttributes oldAttrs, PrintAttributes newAttrs, CancellationSignal cancelSignal, LayoutResultCallback callback, Bundle extras) { if (cancelSignal.isCanceled()) { callback.onLayoutCancelled(); return; } PrintDocumentInfo docInfo = new PrintDocumentInfo.Builder("打印内容.txt") .setContentType(PrintDocumentInfo.CONTENT_TYPE_TEXT) .build(); callback.onLayoutFinished(docInfo, true); } @Override public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancelSignal, WriteResultCallback callback) { try (FileOutputStream fos = new FileOutputStream(destination.getFileDescriptor())) { fos.write(content.getBytes(StandardCharsets.UTF_8)); callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES}); } catch (IOException e) { callback.onWriteFailed(e.getMessage()); } } }, null); }
四、注意事项
- 编码一致性:原Dataflex模板可能用GBK编码,读取时需指定对应字符集,避免乱码。
- 格式对齐:原打印是固定宽度布局,替换变量时必须用
String.format处理对齐、补空格或截断,保证布局不变。 - 异常处理:读取文件、打印过程中需捕获
IOException,处理用户取消、打印失败等场景。 - 模板分析:若不确定下划线对应的变量,先回溯原Dataflex代码,明确每个下划线区域的业务含义,再整理映射规则。
内容的提问来源于stack exchange,提问作者El_Microman
相关产品推荐
相关产品推荐

