Java实现后台打印--本教程适合小白不适合高手
打印完善:接到命令继续改进打印,放弃了之前写的web打印方式,相比web打印这种方式可以进行直接打印,不跳转到预览页,缺点就是有点麻烦。哈哈哈,不过可以学到不少东西。
整体思路:1、Linux的web后台发送打印消息(使用ZMQ发送其他的也可以)
2、ZMQ接收消息(打印信息),组织信息,打印
机器A--》添加访客--》发出打印消息(Linux后台)--》机器A的可执行Jar程序接收消息--》完成
最新更新:后台打印需要配合操作系统,一般都是将应用部署到Linux系统上,所以需要你的liunx机器支持打印机,这样一来打印机就固定了。如果打印只固定在某一个地方,肯定只有一台打印机器,后台打印是最好的选择,但是我们的项目应用的时候有多个打印地点这样,后台打印就不符合需求了,所以我最后又推翻了自己的后台打印,,,,,,。博客还是留着吧。web打印是我最后的选择。
公司项目需要打印一个小小通行证,试了很多方法想着页面都已经出来了,直接网页打印得了于是乎看到各种网页打印的方法:其中稍微好点的就是用几个插件Lodop(部分免费)---打出来有水印,去水印要5800元。其他的几个插件大同小异不是要钱就是要钱。web打印还有一个共同特点需要安装exe程序,这样的话太不方便了,一个成熟的产品哪能这样啊。于是老大让我研究java打印。其实web打印(不使用插件一定会弹窗的)我已经写好了,但是体验度不好,综合有以下几点:
1、不能直接打印,非得弹出打印预览页,不友好,我这项目使用的东西是固定的不需要打印预览
package com.czht.wdp.gateway.print.service.impl;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.czht.wdp.common.util.DateUtil;
import com.czht.wdp.common.util.PropertiesUtil;
import com.czht.wdp.constant.ConstantUtil;
import com.czht.wdp.core.sys.dto.SysUserDto;
import com.czht.wdp.gateway.biz.dto.UserDto;
import com.czht.wdp.gateway.biz.service.UserService;
import com.czht.wdp.gateway.constant.PropertiesConstant;
import com.czht.wdp.gateway.print.service.PrintService;
/**
* 描述:通行证打印
* @author create or edit by zhouwen
* @date 2018年6月26日--上午9:13:55
*/
@Service
public class PrintServiceImpl implements PrintService {
private static Properties props = PropertiesUtil.readPropertyByEncoding("/conf/resource/development/resource.properties","UTF-8");
private static UserDto userDto;
private static SysUserDto sysUserDto;
private static Integer todayVisitorNum;
@Autowired
private UserService userService;
@Override
public void printVisitorInfo(UserDto dto,HttpServletRequest request) {
userDto = userService.getNewestUserByName(dto.getName());
//接待人名字
userDto.setFaceFdfsId(dto.getFaceImg1Url());
userDto.setVistorName(dto.getVistorName());
todayVisitorNum = userService.getTodayVisitorNum();
HttpSession session = request.getSession();
sysUserDto = (SysUserDto) session.getAttribute(ConstantUtil.SESSION_USER_KEY);
printPrepare();
}
private void printPrepare() {
// 创建一个工作文档 book
Book book = new Book();
// 设置打印方式 竖打
PageFormat format = new PageFormat();
format.setOrientation(PageFormat.PORTRAIT);
//通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符
Paper paper = new Paper();
//纸张大小
paper.setSize(227, 400);
//A4(595 X 842)设置打印区域,其实0,0应该是72,72,因为A4纸的默认X,Y边距是72
paper.setImageableArea(3, 0, 220,350);
format.setPaper(paper);
//将PageFormat和 Printable 添加到书中,组成一个页面
book.append(new PrintExecuteClass(),format);
//获取打印服务对象
PrinterJob job = PrinterJob.getPrinterJob();
//设置打印类
job.setPageable(book);
//可以用printDialog显示打印对话框,在用户确认后打印;也可以直接打印
// boolean a = job.printDialog();
// if (a) {
try {
job.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}
class PrintExecuteClass implements Printable{
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
//输出内容
// 转换Graphics2D
Graphics2D graphics2d = (Graphics2D) graphics;
// 设置打印属性
graphics2d.setBackground(Color.black);
graphics2d.setColor(Color.black);
if (pageIndex == 0) {
// 设置打印字体(字体名称、样式和点大小)(字体名称可以是物理或者逻辑名称)
// Java平台所定义的五种字体系列:Serif、SansSerif、Monospaced、Dialog 和 、、// DialogInput
//Font font = new Font("宋体",Font.PLAIN,11);
//Font font1 = new Font("宋体",Font.PLAIN,8);
//将字体样式set到 graphics2d 中
// graphics2d.setFont(font);
//设置打印线的属性
//float[] dash = {3.0f};
//画虚线设置
//graphics2d.setStroke(new BasicStroke(1.5f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER,2.0f,dash,0.0f)); // 字体高度
//float heigth = font.getSize2D();
// -1- 用Graphics2D直接输出
//首字符的基线(右下部)位于用户空间中的 (x, y) 位置处
//Image src = Toolkit.getDefaultToolkit().getImage("http://192.168.10.235:8888/group1/M00/00/01/wKgK61sxtEmIQoVNAAAQHNMNX0cAAAAbgn8BVcAABA0935.jpg");
//graphics2d.drawImage(src,(int)x,(int)y,c);
// int img_Height=src.getHeight(c);
// int img_width=src.getWidth(c);
//graphics2d.drawString(str, (float)x, (float)y+1*heigth+img_Height);
//graphics2d.setFont(font1);
//drawingTable(graphics2d);
//graphics2d.drawString(str, (float)x, (float)y+2*heigth+img_Height);
/*Line2D line = new Line2D.Double(30,30,100,100);
graphics2d.draw(line);*/
/*graphics2d.drawLine(40,160,280,160);
graphics2d.drawLine((int)x,(int)(y+3*heigth+img_Height+10),(int)x+50,(int)(y+3*heigth+img_Height+10));
graphics2d.drawImage(src,(int)x,(int)(y+5*heigth+img_Height+11),c); */
fillContent(graphics2d,pageFormat);
//让当前线程等待200毫秒,取图片需要时间
/* Thread th=Thread.currentThread();
try {
th.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
return PAGE_EXISTS;
}
return NO_SUCH_PAGE;
}
//画表格
public void drawingTable(Graphics2D graphics2d){
//设置线条粗细
graphics2d.setStroke(new BasicStroke(0.7f));
//设置画矩形的原点
int restangle_x = 3;
int restangle_y = 123;
//间隔 space_1固定栏目的,space_2填写的信息
int space_1 = 45;
int space_2 = 55;
//画矩形
Rectangle2D rect = new Rectangle2D.Double(restangle_x,restangle_y,197,125);//声明并创建矩形对象,矩形的左上角是(10,10),宽是80,高是40
graphics2d.draw(rect);
//画横线
int line_first_y = 148;
Line2D line1 = new Line2D.Double(3,line_first_y,200,line_first_y);
Line2D line2 = new Line2D.Double(3,line_first_y+25,200,line_first_y+25);
Line2D line3 = new Line2D.Double(3,line_first_y+50,200,line_first_y+50);
Line2D line4 = new Line2D.Double(3,line_first_y+75,200,line_first_y+75);
graphics2d.draw(line1);
graphics2d.draw(line2);
graphics2d.draw(line3);
graphics2d.draw(line4);
//画竖线
Line2D verticalLine1 = new Line2D.Double(restangle_x+space_1,restangle_y,restangle_x+space_1,restangle_y+5*25);
Line2D verticalLine2 = new Line2D.Double(restangle_x+space_1+space_2,restangle_y,restangle_x+space_1+space_2,restangle_y+1*25);
Line2D verticalLine3 = new Line2D.Double(restangle_x+2*space_1+space_2,restangle_y,restangle_x+2*space_1+space_2,restangle_y+1*25);
Line2D verticalLine4 = new Line2D.Double(restangle_x+space_1+space_2,restangle_y+2*25,restangle_x+space_1+space_2,restangle_y+3*25);
Line2D verticalLine5 = new Line2D.Double(restangle_x+2*space_1+space_2,restangle_y+2*25,restangle_x+2*space_1+space_2,restangle_y+3*25);
Line2D verticalLine6 = new Line2D.Double(restangle_x+space_1+space_2,restangle_y+4*25,restangle_x+space_1+space_2,restangle_y+5*25);
Line2D verticalLine7 = new Line2D.Double(restangle_x+2*space_1+space_2,restangle_y+4*25,restangle_x+2*space_1+space_2,restangle_y+5*25);
graphics2d.draw(verticalLine1);
graphics2d.draw(verticalLine2);
graphics2d.draw(verticalLine3);
graphics2d.draw(verticalLine4);
graphics2d.draw(verticalLine5);
graphics2d.draw(verticalLine6);
graphics2d.draw(verticalLine7);
}
//向表格中填内容
public void fillContent(Graphics2D graphics2d,PageFormat pageFormat){
//第一步打印标题
// 打印起点坐标
double x = pageFormat.getImageableX();
//double y = pageFormat.getImageableY();
String text = getEncodingByUTF8(props.getProperty("PRT_VIT_TITLE"));
// 计算出中心点,并且绘制出文字
Font font1 = new Font("宋体",Font.PLAIN,12);
graphics2d.setFont(font1);
FontMetrics fontMetrics = graphics2d.getFontMetrics(graphics2d.getFont());
// 文字宽度
int textWidth = fontMetrics.stringWidth(text);
float heigth = graphics2d.getFont().getSize2D();
float prt_x = (float)(x+(200-textWidth))/2;
float prt_y = (float)(3+heigth);
graphics2d.drawString(text,prt_x , prt_y);
//第二步打印图片
URL url = null;
try {
if(userDto.getFaceFdfsId().indexOf("http:")!=-1){
url = new URL(userDto.getFaceFdfsId());
}else {
url = new URL(PropertiesConstant.FDFS_DOMAIN+"/"+userDto.getFaceFdfsId());
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
Image src = Toolkit.getDefaultToolkit().getImage(url);
//获取的图片进行放缩:91*121
@SuppressWarnings("unused")
Image scaledInstance = src.getScaledInstance(91, 121, 2);
Component c = null;
//int img_Height=src.getHeight(c);
//int img_width=scaledInstance.getWidth(c);
float prt_img_x = (float)((200-91)/2+x+10);
float prt_img_y = (float)(3+prt_y+5);
graphics2d.drawImage(src,(int)prt_img_x,(int)prt_img_y,70,90,c);
//画表格
drawingTable(graphics2d);
//向表中填写数据
Font font2 = new Font("宋体",Font.PLAIN,8);
graphics2d.setFont(font2);//props.getProperty("PRT_VIT_TITLE")
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_NAME")), (float)5, (float)140);
graphics2d.drawString(userDto.getName(), (float)55, (float)140);
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_PHONE")), (float)105, (float)140);
graphics2d.drawString(userDto.getPhone(), (float)150, (float)140);
//第二行
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_ID_NUMBER")), (float)5, (float)165);
graphics2d.drawString(userDto.getIdentityNo(), (float)55, (float)165);
//第三行
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_REASON")), (float)5, (float)190);
graphics2d.drawString(userDto.getVistorReason(), (float)55, (float)190);
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_ENTOURAGE")), (float)105, (float)190);
graphics2d.drawString("0", (float)150, (float)190);
//
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_TIME")), (float)5, (float)215);
graphics2d.drawString(DateUtil.getDateTime(userDto.getCreated()), (float)55, (float)215);
//第三行
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_DESK_CLERK")), (float)5, (float)241);
graphics2d.drawString(userDto.getVistorName(), (float)55, (float)241);
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_SIGNED")), (float)105, (float)241);
//graphics2d.drawString("*", (float)150, (float)241);
graphics2d.drawString(getEncodingByUTF8(props.getProperty("PRT_VIT_OPERATOR"))+":"+sysUserDto.getUsername(), (float)5, (float)258);
graphics2d.drawString(dealWithNumber(todayVisitorNum), (float)100, (float)258);
}
//处理编号的
public String dealWithNumber(Integer number){
String str = number.toString();
String retStr = "NO.";
Integer len = str.length();
if(len<6){
for(int i=6-len;i>0;i--){
retStr += "0";
}
}
retStr += str;
return retStr;
}
//转编码问题
public String getEncoding(String str) {
String encode = "GB2312";
try {
if (str.equals(new String(str.getBytes(encode), encode))) {
String s = encode;
return s;
}
} catch (Exception exception) {
}
encode = "ISO-8859-1";
try {
if (str.equals(new String(str.getBytes(encode), encode))) {
String s1 = encode;
return s1;
}
} catch (Exception exception1) {
}
encode = "UTF-8";
try {
if (str.equals(new String(str.getBytes(encode), encode))) {
String s2 = encode;
return s2;
}
} catch (Exception exception2) {
}
encode = "GBK";
try {
if (str.equals(new String(str.getBytes(encode), encode))) {
String s3 = encode;
return s3;
}
} catch (Exception exception3) {
}
return "";
}
public String getEncodingByUTF8(String str){
String encoding = getEncoding(str);
String retStr = null;
if(!encoding.equals("UTF-8")){
try {
retStr = new String(str.getBytes(encoding),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return retStr;
}
}
}
上一篇: java动态编译——JavaFileManager详解
下一篇: 通过lambda实现菜单树形结构