-2

我在打印发票时遇到字符串格式问题。发票没有按照我的要求正确对齐。该代码只需向热敏打印机生成发票账单。如果找不到打印机设备,它将获得系统的默认打印介质。我的代码如下。

public static String padRight(字符串s,int n){return String.format(“%-”+n+“s”,s);}public static String padRightInt(int s,int n){return String.format(“%-”+n+“d”,s);}公共静态void printIvoice(节点节点){Printer Printer=Printer.getDefaultPrinter();PrinterJob PrinterJob=打印机作业.createPrinterJop(打印机);双标度=0.791;node.getTransforms().add(新的Scale(Scale,Scale));布尔成功=printerJob.printPage(节点);if(成功){printerJob.endJob();}}公共静态节点getPrintableText(String[]产品){标签文本=新标签();text.setFont(Font.Font(“单间距规则”,FontWeight.LIGHT,11));StringBuilder StringBuilder=新的StringBuilder=();stringBuilder.append(“公司名称”);stringBuilder.append(“------------------------------------------”+“\n”);stringBuilder.append(String.format(“%-40s%5s%10s\n”,“项目”,“数量”,“价格”);stringBuilder.append(String.format(“%-40s%5s%10s\n”,“----”,“---”,“-----”);for(字符串产品:产品){if(product.trim().length()>25){String firstLine=product.trim().substring(0,25);stringBuilder.append(firstLine).appende(“”).appent(“\n”);String lastLine=product.trim().substring(25);int spaces=50-lastLine.length();stringBuilder.append(String.format(padRight(lastLine,空格),lastLine)+String.format(padRightInt(1,10),1)+“”+String.format(padRightInt(1000,10),1000)).append(“\n”);}其他{字符串温度=product.trim();int空格=50-临时长度();stringBuilder.append(String.format(padRight(temp,spaces),temp)+String.format(pad_RightInt(1,10),1)+“”+String.format(padRightInt(1000,10),1000)).appende(“\n”);}}stringBuilder.append(“_____________________________________________”+“\n”);stringBuilder.append(“净金额5000”+“\n”);stringBuilder.append(“_____________________________________________”+“\n”);stringBuilder.append(“非常感谢!”+“\n”);text.setText(stringBuilder.toString());返回文本;}

下面是调用此代码的主要方法。

公共静态void main(String[]args){字符串[]productName={“安卓”,“Mac OS”,“Windows 10操作系统”,“Linux操作系统”,“Windows服务器操作系统”};节点节点=getPrintableText(productName);printIvoice(节点);}

代码输出如下

在此处输入图像描述

我想根据产品名称长度对齐输出。我试着通过额外的空格来格式化它,但它不起作用。我想把数量和价格列正确对齐。请帮忙。提前谢谢。

22
  • 1
    健全性检查:当您将输出打印到控制台时,其格式是否正确?如果不是,那么请注意,这个问题与JavaFX没有直接关系,在这种情况下,删除对JavaFX的所有引用将使问题更加集中(也更容易提供适当的最小可再现示例在这种情况下)。
    – 斯劳
    评论 6月15日11:41
  • 4
    字体分为固定宽度字体和不等宽度字体。如果您想使用它进行计费,请确保使用固定宽度的字体。这样,您可以使用多少字符宽度来进行排列和对齐。 评论 6月15日11:46
  • 1
    是的,那是一种等宽字体,因此不符合您的计算 评论 6月15日12:53
  • 1
    我看不出这段代码在现实中会有什么用处。您当前正在对大多数输出进行硬编码。肯定会的全部的需要参数化才能实际使用 评论 6月15日13:24
  • 1
    兄弟,这与数据库通信无关。它将格式化并打印数据。 评论 6月15日16:55

1答案1

重置为默认值
5

这只是一个概念证明。

因此,程序只需确认打印的布局内容,然后将其发送到默认打印机。

因此,这个程序也非常简短和简单。刚好可以完成概念验证。

PrintCanvasExample2.java打印画布示例2.java

软件包com.example.demoticketprintapp;导入javafx.application。应用程序;导入javafx.print.*;导入javafx.sene。节点;导入javafx.sene。场景;导入javafx.scene.canvas。帆布;导入javafx.scene.canvas。图形上下文;导入javafx.scene.layout。StackPane;导入javafx.scene.paint。颜色;导入javafx.scene.text。字体;导入javafx.stage。阶段;公共类PrintCanvasExample2扩展应用程序{静态字符串发票;public static String getPrintableText(String[]产品){//标签文本=新标签();//text.setFont(Font.Font(“单间距规则”,FontWeight.LIGHT,11));StringBuilder StringBuilder=新的StringBuilder=();stringBuilder.append(“公司名称”);stringBuilder.append(“-----------------------------------------”+“\n”);stringBuilder.append(String.format(“%-24s%5s%10s\n”,“项目”,“数量”,“价格”);stringBuilder.append(String.format(“%-24s%5s%10s\n”,“----”,“-----”,“----------”);for(字符串产品:产品){stringBuilder.append(formatTemplateString(product,112500));}stringBuilder.append(“____________________________________________”+“\n”);stringBuilder.append(“净金额5000”+“\n”);stringBuilder.append(“____________________________________________”+“\n”);stringBuilder.append(“非常感谢!”+“\n”);//调试System.out.println(stringBuilder.toString());return stringBuilder.toString();}私有void打印(节点节点){打印机作业=打印机作业.createPrinterJob();if(作业!=空){//打印节点布尔打印=job.printPage(节点);if(打印){//结束打印机作业作业.endJob();}其他{System.out.println(“打印失败”);}}其他{System.out.println(“无法创建打印机作业。”);}}公共静态字符串格式TemplateString(String str,long num1,long num2){String formattedStr=String.format(“%-24s”,str);String formattedNum1=String.format(“%5d”,num1);String formattedNum2=String.format(“%10d”,num2);字符串rt=“”;如果(字符串长度()>25){if(字符串长度()<=44){rt=str+“\n”+“”.repeat(24)+“”+formattedNum1+“”+formattedNum2;}否则,如果(字符串长度()>44){字符串str1=str.substring(0,44);字符串str2=str.substring(44);rt=str1+“\n”+String.format(“%-24s”,str2)+“”+formattedNum1+“”+formattedNum2;}}其他{rt=格式化Str+“”+格式化Num1+“”+formattedNum2;}return rt+“\n”;}@覆盖公共无效启动(阶段primaryStage){Canvas Canvas=新Canvas(400,300);GraphicsContext gc=canvas.getGraphicsContext2D();gc.setFill(颜色.WHITE);gc.fillRect(0,0,canvas.getWidth(),canvas.getHeight());//设置字体//Linux操作系统gc.setFont(新字体(“单间距规则”,12));//WIndows公司//gc.setFont(新字体(“Courier new”,12));gc.setFill(颜色.BLACK);//绘制文本//gc.fillText(发票2、50、50);gc.fillText(发票,50,50);打印(画布);StackPane根=新StackPane();场景场景=新场景(root,400,300);primaryStage.setTitle(“打印画布示例”);primaryStage.setScene(场景);primaryStage.show();}公共静态void main(String[]args){String[]产品名称={“安卓”,“Mac OS”,“Windows 10操作系统”,“Linux操作系统”,“Windows服务器操作系统”};invoice=getPrintableText(productName);启动(args);}}

FormatTemlate:44字符宽度

  • 如果项目名称长度>24,请将其保留在一行中
  • 如果项目名称长度>44,请将其拆分为两行
公共静态字符串格式TemplateString(String str,long num1,long num2){String formattedStr=String.format(“%-24s”,str);String formattedNum1=String.format(“%5d”,num1);String formattedNum2=String.format(“%10d”,num2);字符串rt=“”;如果(字符串长度()>25){if(字符串长度()<=44){rt=str+“\n”+“”.repeat(24)+“”+formattedNum1+“”+formattedNum2;}否则,如果(字符串长度()>44){字符串str1=str.substring(0,44);字符串str2=str.substring(44);rt=str1+“\n”+String.format(“%-24s”,str2)+“”+formattedNum1+“”+formattedNum2;}}其他{rt=格式化Str+“”+格式化Num1+“”+formattedNum2;}return rt+“\n”;}

调试输出

公司名称-------------------------------------------物料数量价格----                      -----  ----------安卓1 12500Mac OS 1 12500Windows 10操作系统1       12500Linux操作系统1 12500Windows Server OS 1 12500___________________________________________净金额5000___________________________________________非常感谢!

打印机输出:

在此处输入图像描述

  • 如果项目名称长度>24&&<44,请将其保留在一行中
  • 如果项目名称长度>44,请将其拆分为两行

Item name=“Windows 10 Operating System Windows 10 Operation System-long name”

在此处输入图像描述

JDK+JavaFX-祖鲁-21.0.3.fx-Zulu

5
  • 兄弟,我不明白这个想法。您向画布提供了硬编码的格式化数据。但问题中的数据只是一个示例,每次打印都会更改。因此需要根据字符串长度动态格式化。你能建议点别的吗? 评论 6月16日9:56
  • 2
    (1) 此代码作为POC用于验证两件事,1。字母数字空格的排版可以使用特定字体对齐(单倍行距规则或其他字体)。2.您认为前面提供的示例(github)是AWT示例,而不是JavaFX示例。(2) 如果你StringBuilder StringBuilder=新的StringBuilder=();stringBuilder.append(“公司名称”);stringBuilder.append(“------------------------------------------------”+“\n”);最终可以组合成My测试数据的文本格式,并可以应用于我上面的程序段gc.fillText(“公司名称”。。。。 评论 6月16日10:04
  • 2
    @Qaisar Shabbir我更新我的代码添加formatTemplateString格式 评论 6月16日11:50
  • 谢谢兄弟,你帮了我很多。只是稍微修改了一下你的解决方案。不需要这个条件if(字符串长度()<=44){。此外子字符串(0,24)提供平滑的结果。这两个更新都位于formatTemplateString()格式功能。 评论 6月16日18:12
  • 2
    @Qaisar Shabbir(1)如果(str.length()<=44),则不需要此条件,(2)我的代码是如果项目名称长度>44,请将其拆分为两行如果项目名称长度>24,请将其保留在一行中(3)此POC程序的问题之一是我不知道Item的长度规格。最长的长度是多少?所以我假设(a)它将超过24而不超过边界(44),(b)它也有可能超过边界(40),(c)即使它将超过88(两列)(我没有在这部分写逻辑) 评论 6月17日3:13

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.