之前通过网上查询java实现打印机打印功能的方法大部分都是通过SimpleDoc类构件打印机的打印文件属性,通过PrintJob的Print()实现打印,但是打印出来的都是乱码。
首先考虑能不能打印文件,因为程序部署在服务器端,需要直接控制前端设备打印,所以需要无界面化操作,我使用的代码:
public static void PDFprint(File file, String printerName) throws Exception {
PDDocument document = null;
try {
document = PDDocument.load(file);
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setJobName(file.getName());
if (printerName != null) {
// 查找并设置打印机
// 获得本台电脑连接的所有打印机
// PrintService[] printServices = PrinterJob.lookupPrintServices();
// if (printServices == null || printServices.length == 0) {
// System.out.print("打印失败,未找到可用打印机,请检查。");
// return;
// }
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
// // 匹配指定打印机
// for (int i = 0; i < printServices.length; i++) {
// System.out.println(printServices[i].getName());
// if (printServices[i].getName().contains(printerName)) {
// printService = printServices[i];
// break;
// }
// }
if (printService != null) {
printJob.setPrintService(printService);
} else {
System.out.print("打印失败,未找到名称为" + printerName + "的打印机,请检查。");
return;
}
}
// 设置纸张及缩放
PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
// 设置多页打印
Book book = new Book();
PageFormat pageFormat = new PageFormat();
// 设置打印方向
pageFormat.setOrientation(PageFormat.PORTRAIT);// 纵向
pageFormat.setPaper(getPaper());// 设置纸张
book.append(pdfPrintable, pageFormat, document.getNumberOfPages());
printJob.setPageable(book);
printJob.setCopies(1);// 设置打印份数
// 添加打印属性
HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet();
pars.add(Sides.DUPLEX); // 设置单双页
printJob.print(pars);
} finally {
if (document != null) {
try {
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
生成pdf很简单,直接使用POI,这里展示一个PDFUTIL:
package com.bhne.utils;
import java.awt.Color;
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
public class PDFUtil {
/**
* document对象
*/
private static Document document = null;
/**
* 创建一个书写器,布局文本位置
* @param leftSize 居左
* @param rightSize 居右
* @param onSize 居上
* @param underSize 居下
* @param path 存储位置
* @throws Exception 初始化PDF错误
*/
public PDFUtil(Integer leftSize , Integer rightSize , Integer onSize , Integer underSize, String path) throws Exception {
try{
// 新建document对象 第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。
document = new Document(PageSize.A4, leftSize, rightSize, onSize, underSize);
// 建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(path));
// 打开文件
document.open();
}catch (Exception e){
e.printStackTrace();
System.out.println("PDF初始化错误");
}
}
/**
* 书写每一个段落选择的字体
*
* @param fontType
* 0 //楷体字
* 1 //仿宋体
* 2 //黑体
* 字体需要可在追加
* @return
* @throws IOException
* @throws DocumentException
*/
public BaseFont addFontType(Integer fontType) {
BaseFont baseFont = null;
try{
switch (fontType){
case 0:
//楷体字
baseFont = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
break;
case 1:
//仿宋体
baseFont = BaseFont.createFont("c://windows//fonts//SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
break;
case 2:
//黑体
baseFont = BaseFont.createFont("c://windows//fonts//SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
break;
}
return baseFont;
}catch (Exception e){
System.out.println("选择字体异常");
e.printStackTrace();
}
return baseFont;
}
/**
* 添加段落 - 段落位置( 0 居左 1 居中 2 居右)
* @param fontType 选择字体
* 0 //楷体字
* 1 //仿宋体
* 2 //黑体
* @param fontSize 字体大小
* @param color 字体颜色
* @param alignment 0 居左 1 居中 2 居右
* @param text 文本内容
*/
public void addParagraph(Integer fontType , Integer fontSize,Integer alignment ,String text){
try{
BaseFont chinese =addFontType(fontType);
Font font = new Font(chinese, fontSize, com.lowagie.text.Font.COURIER);
Paragraph paragraph =new Paragraph(text,font);
//居中显示
paragraph.setAlignment(alignment);
document.add(paragraph);
}catch (Exception e){
e.printStackTrace();
System.out.println("添加段落异常");
}
}
/**
* 添加段落 - 首行缩进
* @param fontType 选择字体
* 0 //楷体字
* 1 //仿宋体
* 2 //黑体
* @param fontSize 字体大小
* @param color 字体颜色
* @param index 首行缩进
* @param text 文本内容
*/
public void addTextIndent(Integer fontType , Integer fontSize,Color color ,Integer index ,String text){
try{
BaseFont chinese =addFontType(fontType);
Font font = new Font(chinese, fontSize, Font.COURIER,color);
Paragraph paragraph =new Paragraph(text,font);
//设置首行缩进
paragraph.setFirstLineIndent(index);
document.add(paragraph);
}catch (Exception e){
e.printStackTrace();
System.out.println("添加段落异常");
}
}
/**
* 添加新的一页
*/
public void addPage(){
try{
document.newPage();
}catch (Exception e){
e.printStackTrace();
System.out.println("添加段落异常");
}
}
/**
* 换行
* 传入1是一行,以此递增
* @param lineNum 换的行数
*/
public void newLine(Integer lineNum) {
try{
for(int i =0 ; i<lineNum ; i++){
document.add(new Paragraph("\n"));
}
}catch (Exception e){
e.printStackTrace();
System.out.println("换行错误");
}
}
/**
* 关闭文档
*/
public void close (){
// 关闭文档
document.close();
}
}
问题一:服务器端部署打印服务,util方法中使用的字体是否存在;
问题二:服务器端需要安装打印机驱动,系统才能正确调用到打印机,但是windowsserver一般很少有打印机驱动的支持。
问题三:程序打印的是PDF,此方法通过POI生成的word是否可以打印?