在网上找了不少通过jdk的printService服务打印pdf的博客,都大同小异,打印调用了但是没有真的打印,最后终于找到一个可用的,这里记录一下。
首先通过maven引入依赖:
org.apache.pdfbox
pdfbox
2.0.6
最后使用工具类:
package com.ruoyi.mrs.utils;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.Sides;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterJob;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author fmi110
* @description 打印工具类
* @date 2021/11/16 14:22
*/
public class PrintUtil {
private static final Logger log = LoggerFactory.getLogger(PrintUtil.class);
/**
* 寻找指定的打印机
* @param printerName
* @return
*/
public static PrintService lookupPrinter(String printerName) {
PrintService service = null;
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
if (printServices == null || printServices.length == 0) {
throw new BusinessException("未获取到打印服务");
}
List printerNames = Arrays.stream(printServices).map(p -> p.getName()).collect(Collectors.toList());
log.info(">>>>可选的打印机:{}", printerNames);
for (int i = 0; i < printServices.length; i++) {
String name = printServices[i].getName().toLowerCase();
log.info("printName{}:{}", i, name);
if (name.contains(printerName.toLowerCase())) {
service = printServices[i];
break;
}
}
if (service == null) {
throw new BusinessException("未找到指定的打印机:" + printerName + ",可选打印服务:" + printerNames);
}
return service;
}
public static void print(String filePath, String printerName, PrintRequestAttributeSet aset) throws Exception {
print(new File(filePath), printerName, aset);
}
/**
* 打印指定文件
* @param file
* @param printerName
* @param aset 打印属性,可通过这个设置打印份数
* @throws Exception
*/
public static void print(File file, String printerName, PrintRequestAttributeSet aset) throws Exception {
if (file == null) {
log.error("传入的文件为空");
throw new Exception("传入的文件为空");
}
if (!file.exists()) {
log.error("文件不存在:" + file.getAbsolutePath());
throw new Exception("文件不存在:" + file.getAbsolutePath());
}
PrintService printService = lookupPrinter(printerName);
if (null == aset) {
aset = getPrintRequestAttributeSet(); // 获取打印参数
}
PDDocument document = PDDocument.load(file);
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setJobName(file.getName());
printJob.setPrintService(printService); // 选择打印机
//设置纸张及缩放
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);
try {
printJob.print(aset);
} catch (Exception e) {
e.printStackTrace();
log.error("打印机打印异常:{}", e.getMessage());
throw new Exception("打印机打印异常:" + e.getMessage());
} finally {
IOUtils.closeQuietly(document);
}
}
private static PrintRequestAttributeSet getPrintRequestAttributeSet() {
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(1)); //份数
aset.add(MediaSizeName.ISO_A4); //纸张
// aset.add(Finishings.STAPLE);//装订
aset.add(Sides.ONE_SIDED);//单双面
return aset;
}
/**
* 设置打印份数
*
* @param copy
* @return
*/
public static PrintRequestAttributeSet getPrintRequestAttributeSet(int copy) {
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(copy)); //份数
aset.add(MediaSizeName.ISO_A4); //纸张
// aset.add(Finishings.STAPLE);//装订
aset.add(Sides.ONE_SIDED);//单双面
return aset;
}
/**
* 将图片转换成pdf
*
* @return
* @throws Exception
*/
public static byte[] img2PDF(List images) throws Exception {
Document doc = new Document(PageSize.A4, 0, 0, 36.0F, 36.0F);//普通a4
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
PdfWriter.getInstance(doc, pdfOut);
doc.open();
for (byte[] image : images) {
com.itextpdf.text.Image pic = com.itextpdf.text.Image.getInstance(image);
pic.setScaleToFitLineWhenOverflow(true);
doc.add(pic);
}
doc.close();
byte[] pdf = pdfOut.toByteArray();
IOUtils.closeQuietly(pdfOut);
return pdf;
}
/**
* 图片缩放成A4尺寸,转换为pdf文件
*
* @param imagePath
* @param descfolder
* @return
* @throws Exception
*/
public static String img2PDF(String imagePath, String descfolder, String pdfName) {
return img2PDF(Arrays.asList(imagePath), descfolder, pdfName);
}
/**
* 图片缩放成A4尺寸,转换为pdf文件
*
* @param imgPaths
* @param descfolder
* @return
* @throws Exception
*/
public static String img2PDF(List imgPaths, String descfolder) {
String pdfName = System.currentTimeMillis() + ".pdf";
return img2PDF(imgPaths, descfolder, pdfName);
}
public static String img2PDF(List imgPaths, String descfolder, String pdfName) {
pdfName = StringUtils.isEmpty(pdfName) ? System.currentTimeMillis() + ".pdf" : pdfName;
String pdfPath = "";
FileOutputStream fos = null;
try {
File file = new File(descfolder);
if (!file.exists()) {
file.mkdirs();
}
pdfPath = descfolder + "/" + pdfName;
Document doc = new Document(PageSize.A4, 0, 0, 0, 0);
fos = new FileOutputStream(pdfPath);
PdfWriter.getInstance(doc, fos);
doc.open();
for (String imagePath : imgPaths) {
com.itextpdf.text.Image image = image = com.itextpdf.text.Image.getInstance(imagePath);
image.scaleAbsolute(PageSize.A4.getWidth(), PageSize.A4.getHeight());
doc.add(image);
}
doc.close();
log.info("生成pdf成功:{}", pdfPath);
} catch (Exception e) {
e.printStackTrace();
log.error("生成pdf异常:" + e.getMessage());
throw new BusinessException("生成pdf异常:" + e.getMessage());
} finally {
IOUtils.closeQuietly(fos);
}
return pdfPath;
}
public static void main(String[] args) throws Exception {
File file = new File("D:\\test\\2.pdf");
print(file, "HP Las", getPrintRequestAttributeSet(1));
// PDDocument document = PDDocument.load(file);
// PrinterJob printJob = PrinterJob.getPrinterJob();
// printJob.setJobName(file.getName());
// PrintService printService = lookupPrinter("HP Las");
// printJob.setPrintService(printService);
//
// //设置纸张及缩放
// 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.ONE_SIDED); //设置单双页
// printJob.print(pars);
}
public static Paper getPaper() {
Paper paper = new Paper();
// 默认为A4纸张,对应像素宽和高分别为 595, 842
int width = 595;
int height = 842;
// 设置边距,单位是像素,10mm边距,对应 28px
int marginLeft = 10;
int marginRight = 0;
int marginTop = 10;
int marginBottom = 0;
paper.setSize(width, height);
// 下面一行代码,解决了打印内容为空的问题
paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
return paper;
}
}
通过main函数可测试结果。