只要你能看懂中文就会用,直接CV直接改,讲究的就是CV大法的魅力!!!
?
我们需要了解图像尺寸和物理尺寸之间的转换关系。
在图像处理中,通常使用像素作为图像的尺寸单位。
而像素和物理尺寸之间通常有一个固定的转换关系,这个关系取决于DPI(每英寸点数)。
在这个问题中,DPI是72,这意味着1英寸等于72像素。
因此,我们可以使用以下公式来进行换算:
图像尺寸(像素) = 物理尺寸(毫米) × (DPI / 25.4)
其中,25.4是1英寸的毫米数。
A4纸的尺寸为210mm×297mm,世界上多数国家所使用的纸张尺寸都是采用这一国际标准.所以210x297mm的尺寸换算成72的图像尺寸的计算结果为:图像的宽度是 595.28 像素,高度是 841.89 像素。
import java.awt.*;
public final class SystemProperties {
public static final double SCREEN_WIDTH = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
public static final double SCREEN_HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
public static final String USER_DIR = System.getProperty("user.dir");
public static final String USER_HOME = System.getProperty("user.home");
public static final String USER_NAME = System.getProperty("user.name");
public static final String FILE_SEPARATOR = System.getProperty("file.separator");
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String PATH_SEPARATOR = System.getProperty("path.separator");
public static final String JAVA_HOME = System.getProperty("java.home");
public static final String JAVA_VENDOR = System.getProperty("java.vendor");
public static final String JAVA_VENDOR_URL = System.getProperty("java.vendor.url");
public static final String JAVA_VERSION = System.getProperty("java.version");
public static final String JAVA_CLASS_PATH = System.getProperty("java.class.path");
public static final String JAVA_CLASS_VERSION = System.getProperty("java.class.version");
public static final String OS_NAME = System.getProperty("os.name");
public static final String OS_ARCH = System.getProperty("os.arch");
public static final String OS_VERSION = System.getProperty("os.version");
public static final String[] FONT_NAME_LIST = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
public static final Font[] FONT_LIST = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
public SystemProperties() {
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class PrintPreviewDialog extends JDialog
implements ActionListener {
private JButton nextButton = new JButton("下一个");
private JButton previousButton = new JButton("以前");
private JButton closeButton = new JButton("关闭");
private JPanel buttonPanel = new JPanel();
private PreviewCanvas canvas;
public PrintPreviewDialog(Frame parent, String title, boolean modal, PrintHelp pt, String str) {
super(parent, title, modal);
canvas = new PreviewCanvas(pt, str);
setLayout();
}
private void setLayout() {
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(canvas, BorderLayout.CENTER);
nextButton.setMnemonic('N');
nextButton.addActionListener(this);
buttonPanel.add(nextButton);
previousButton.setMnemonic('N');
previousButton.addActionListener(this);
buttonPanel.add(previousButton);
closeButton.setMnemonic('N');
closeButton.addActionListener(this);
buttonPanel.add(closeButton);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
// 弹窗xy位置,宽高
this.setBounds((int) ((SystemProperties.SCREEN_WIDTH - 400) / 2), (int) ((SystemProperties.SCREEN_HEIGHT - 400) / 2), 2360, 1180);
}
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == nextButton)
nextAction();
else if (src == previousButton)
previousAction();
else if (src == closeButton)
closeAction();
}
private void closeAction() {
this.setVisible(false);
this.dispose();
}
private void nextAction() {
canvas.viewPage(1);
}
private void previousAction() {
canvas.viewPage(-1);
}
class PreviewCanvas extends JPanel {
private String printStr;
private int currentPage = 0;
private PrintHelp preview;
public PreviewCanvas(PrintHelp pt, String str) {
printStr = str;
preview = pt;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
double xoff;
double yoff;
double scale;
double px = pf.getWidth();
double py = pf.getHeight();
double sx = getWidth() - 1;
double sy = getHeight() - 1;
if (px / py < sx / sy) {
scale = sy / py;
xoff = 0.5 * (sx - scale * px);
yoff = 0;
} else {
scale = sx / px;
xoff = 0;
yoff = 0.5 * (sy - scale * py);
}
g2.translate((float) xoff, (float) yoff);
g2.scale((float) scale, (float) scale);
// 白板xy轴位置,宽高
Rectangle2D page = new Rectangle2D.Double(0, 0, px, py);
g2.setPaint(Color.white);
g2.fill(page);
g2.setPaint(Color.black);
g2.draw(page);
try {
preview.print(g2, pf, currentPage);
} catch (PrinterException pe) {
g2.draw(new Line2D.Double(0, 0, px, py));
g2.draw(new Line2D.Double(0, px, 0, py));
}
}
public void viewPage(int pos) {
int newPage = currentPage + pos;
if (0 <= newPage && newPage < preview.getPagesCount(printStr)) {
currentPage = newPage;
repaint();
}
}
}
}
import com.scwl.printer_jg.model.GoodsDTO;
import com.scwl.printer_jg.model.WeighingListDTO;
import javax.print.*;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Properties;
/**
* @author 小影
* @create 2023-12-22 17:05
* @describe: JFrame:Java图形化界面设计——容器
* java.awt.print.Printable动作事件监听器
* java.awt.print.Printable:通用的打印 API 提供类和接口
*/
public class PrintHelp extends JFrame implements ActionListener, Printable {
public PrintHelp() {
this.setTitle("小影打印测试");// 窗口标题
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds((int) ((SystemProperties.SCREEN_WIDTH - 800) / 2), (int) ((SystemProperties.SCREEN_HEIGHT - 600) / 2), 800, 600);
initLayout();
}
private WeighingListDTO weighingListDTO;// 参数实体类
private int PAGES = 0;
private JTextArea area = new JTextArea();// 用来创建一个默认的文本域
private JPanel buttonPanel = new JPanel();// 创建面板
private JScrollPane scroll = new JScrollPane(area);// 创建窗口
private String printStr;
private JButton printTextButton = new JButton("打印测试");
private JButton previewButton = new JButton("打印预览");
private JButton printText2Button = new JButton("打印测试2");
private JButton printFileButton = new JButton("打印文件");
private JButton printFrameButton = new JButton("Print Frame");
private JButton exitButton = new JButton("退出");
public static void main(String[] args) throws PrinterException {
Book book = new Book();
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
Paper p = new Paper();
p.setSize(595, 283);// 纸张大小单位是像素
p.setImageableArea(1, 5, 590, 282);// A4(595 X 842)设置打印区域,其�?0�?0应该�?72�?72,因为A4纸的默认X,Y边距�?72
pf.setPaper(p);
WeighingListDTO datas = new WeighingListDTO();
datas.setUnitName("XXXXX有限公司称重计量单");
datas.setClientName("客户名称: XXXXX里科技有限公司");
datas.setPlateNumber("闽C:66666");
datas.setOrderNo("过磅单:GB88888888");
datas.setSjName("司机签名:");
datas.setSjPhone("司机电话:");
datas.setYssl("一式三联");
ArrayList<GoodsDTO> goodList = new ArrayList<>();
GoodsDTO goods = new GoodsDTO();
GoodsDTO goods2 = new GoodsDTO();
goods.setGoodsName("物料名称");
goods.setNumber("件数");
goods.setTare("皮重");
goods.setGrossWeight("毛重");
goods.setSuttle("净重");
goods.setCSuttle("纯净重");
goods.setQingTime("轻磅时间");
goods.setZhongTime("重磅时间");
goods2.setGoodsName("皂角");
goods2.setNumber("100");
goods2.setTare("15.76");
goods2.setGrossWeight("49.80");
goods2.setSuttle("34.0400");
goods2.setCSuttle("34.0400");
goods2.setQingTime("2023/12/22 09:30:00");
goods2.setZhongTime("2023/12/22 10:30:00");
goodList.add(goods);
goodList.add(goods2);
datas.setList(goodList);
PrintHelp printHelp = new PrintHelp();
printHelp.init(datas);
book.append(printHelp, pf);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(book);
// job.print();//进行打印
printHelp.setVisible(true); // 打印窗口
}
public void init(WeighingListDTO datas) {
this.weighingListDTO = datas;
}
private void initLayout() {
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(scroll, BorderLayout.CENTER);
printTextButton.setMnemonic('P');
printTextButton.addActionListener(this);
buttonPanel.add(printTextButton);
previewButton.setMnemonic('v');
previewButton.addActionListener(this);
buttonPanel.add(previewButton);
printText2Button.setMnemonic('e');
printText2Button.addActionListener(this);
buttonPanel.add(printText2Button);
printFileButton.setMnemonic('i');
printFileButton.addActionListener(this);
buttonPanel.add(printFileButton);
printFrameButton.setMnemonic('F');
printFrameButton.addActionListener(this);
buttonPanel.add(printFrameButton);
exitButton.setMnemonic('x');
exitButton.addActionListener(this);
buttonPanel.add(exitButton);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
}
/**
* 监听按钮
*
* @param evt
*/
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == printTextButton)
printTextAction();
else if (src == previewButton)
previewAction();
else if (src == printText2Button)
printText2Action();
else if (src == printFileButton)
printFileAction();
else if (src == printFrameButton)
printFrameAction();
else if (src == exitButton)
exitApp();
}
/**
* 打印测试
*/
private void printTextAction() {
printStr = area.getText().trim();
if (printStr != null && printStr.length() > 0) {
PAGES = getPagesCount(printStr);
PrinterJob myPrtJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = myPrtJob.defaultPage();
myPrtJob.setPrintable(this, pageFormat);
if (myPrtJob.printDialog()) {
try {
myPrtJob.print();
} catch (PrinterException pe) {
pe.printStackTrace();
}
}
} else {
// 需要输入内容
JOptionPane.showConfirmDialog(null, "对不起,打印作业为空,打印取消!", "提示"
, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);
}
}
/**
* 打印预览
*/
private void previewAction() {
printStr = area.getText().trim();
PAGES = getPagesCount(printStr);
(new PrintPreviewDialog(this, "打印预览", true, this, printStr)).setVisible(true);
}
private void printText2Action() {
printStr = area.getText().trim();
if (printStr != null && printStr.length() > 0) {
PAGES = getPagesCount(printStr);
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = printService.createPrintJob();
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(this, flavor, das);
try {
job.print(doc, pras);
} catch (PrintException pe) {
pe.printStackTrace();
}
} else {
JOptionPane.showConfirmDialog(null, "Sorry, Printer Job is Empty, Print Cancelled!", "Empty"
, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);
}
}
private void printFileAction() {
JFileChooser fileChooser = new JFileChooser(SystemProperties.USER_DIR);
int state = fileChooser.showOpenDialog(this);
if (state == fileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
PrintService service = ServiceUI.printDialog(null, 200, 200, printService
, defaultService, flavor, pras);
if (service != null) {
try {
DocPrintJob job = service.createPrintJob();
FileInputStream fis = new FileInputStream(file);
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(fis, flavor, das);
job.print(doc, pras);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printFrameAction() {
Toolkit kit = Toolkit.getDefaultToolkit();
Properties props = new Properties();
props.put("awt.print.printer", "durango");
props.put("awt.print.numCopies", "2");
if (kit != null) {
PrintJob printJob = kit.getPrintJob(this, "Print Frame", props);
if (printJob != null) {
Graphics pg = printJob.getGraphics();
if (pg != null) {
try {
this.printAll(pg);
} finally {
pg.dispose();
}
}
printJob.end();
}
}
}
/**
* 退出
*/
private void exitApp() {
this.setVisible(false);
this.dispose();
System.exit(0);
}
/**
* 获取页数数量
*
* @param curStr
* @return
*/
public int getPagesCount(String curStr) {
int page = 0;
int position, count = 0;
String str = curStr;
while (str.length() > 0) {
position = str.indexOf('\n');
count += 1;
if (position != -1)
str = str.substring(position + 1);
else
str = "";
}
if (count > 0)
page = count / 54 + 1;
return page;
}
/**
* 打印模板
*
* @param g 将页面绘制到其中的上下文
* @param pf 正在绘制的页面的大小和方向
* @param page 要绘制的页的从零开始的索引
* @return
* @throws PrinterException
*/
@Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
// 转换成Graphics2D
Graphics2D g2 = (Graphics2D) g;
// 设置打印颜色为黑
// 抗锯齿就是减少图形边缘的锯齿状像素格,使画面看上去更精细而不是满屏的马赛克
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.black);// 黑色
// 打印起点坐标 对象的可成像区域左上方点的x 坐标 和左上的y坐标
double x = pf.getImageableX();// 返回与此 PageFormat 相关 Paper
double y = pf.getImageableY();
switch (page) {
case 0:
// 新建 个打印字体样式(1.字体名称 2.样式(加粗).3字号大小
Font font = new Font("微软雅黑", Font.PLAIN, 16);
// 给g2设置字体
g2.setFont(font);
// 保存虚线的宽
float[] dash1 = {2.0f};
// 设置打印线的属 1.线宽 2 3、不知道 4、空白的宽度 5、虚线的宽度 6、偏移量
g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 2.0f, dash1, 0.0f));
float fontHeigth1 = font.getSize2D();// 字体大小
// 左上40起点 中间160 右边400起点
// 240高起点
// 标题 (渲染的值,X轴,Y轴)
g2.drawString(weighingListDTO.getUnitName(), 220, 40);
// 如果把握不好尺寸就打印(g2.drawString(weighingListDTO.getUnitName() + "2", 50, 20);),然后再自己慢慢推敲出来想要的位置
// g2.drawString(weighingListDTO.getUnitName() + "2", 50, 20);
// g2.drawString(weighingListDTO.getUnitName() + "3", 60, 40);
// g2.drawString(weighingListDTO.getUnitName() + "4", 70, 60);
// g2.drawString(weighingListDTO.getUnitName() + "5", 80, 80);
// g2.drawString(weighingListDTO.getUnitName() + "6", 90, 100);
// g2.drawString(weighingListDTO.getUnitName() + "7", 100, 120);
// g2.drawString(weighingListDTO.getUnitName() + "8", 110, 140);
// g2.drawString(weighingListDTO.getUnitName() + "9", 120, 160);
// g2.drawString(weighingListDTO.getUnitName() + "11", 130, 180);
// g2.drawString(weighingListDTO.getUnitName() + "12", 140, 200);
// g2.drawString(weighingListDTO.getUnitName() + "13", 150, 220);
// g2.drawString(weighingListDTO.getUnitName() + "14", 160, 240);
// g2.drawString(weighingListDTO.getUnitName() + "15", 170, 260);
// 新建个字体
Font font2 = new Font("微软雅黑", Font.PLAIN, 10);
g2.setFont(font2);// 设置字体
g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 2.0f, dash1, 0.0f));
float fontHeigth2 = (int) font.getSize2D();// 字体2的高
int tempHeight = (int) (fontHeigth1 * 2 + 50);// 临时高。字体1的高2倍 +50
Integer hang_juInteger = 15;// 行距
g2.drawString(weighingListDTO.getClientName(), 40, 60); 客户/供应商
g2.drawString(weighingListDTO.getPlateNumber(), 250, 60);// 车牌号
g2.drawString(weighingListDTO.getOrderNo(), 440, 60);// 磅单号
int listY = 80;
for (GoodsDTO dto : weighingListDTO.getList()) {
// 物料名称
g2.drawString(dto.getGoodsName(), 40, listY);
// 件数
g2.drawString(dto.getNumber(), 90,listY);
// 皮重
g2.drawString(dto.getTare(), 130,listY);
// 毛重
g2.drawString(dto.getGrossWeight(), 170,listY);
// 净重
g2.drawString(dto.getSuttle(), 210,listY);
// 纯净重
g2.drawString(dto.getSuttle(), 250,listY);
// 轻榜时间
g2.drawString(dto.getQingTime(), 320,listY);
// 重磅时间
g2.drawString(dto.getZhongTime(), 430,listY);
listY += 20;// 每行间距20像素
}
// 司机签名
g2.drawString(weighingListDTO.getSjName(), 40,230);
// // 司机电话
g2.drawString(weighingListDTO.getSjPhone(), 160,230 );
// // 一式三联
g2.drawString(weighingListDTO.getYssl(), 500, 230);
return PAGE_EXISTS;
default:
return NO_SUCH_PAGE;
}
}
}
如果要改成接口触发打印就需要改一下启动类,否则会报错:java.awt.HeadlessException: null
@SpringBootApplication
public class PrinterJgApplication {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(PrinterJgApplication.class);
builder.headless(false).run(args);
}
}