前言
- 该内容支持三种方式/入参。
- 1、前端表单提交(接收参数为MultipartFile)
- 2、pdf的base64编码流
- 3、pdf的url链接
- 引入pdfbox相关依赖后不多说,直接上代码。
代码实现
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.6</version>
</dependency>
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterJob;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @author
* @version 1.0
* @date 2024-04-01 19:59
* @description
*/
public class Test {
public static void main(String[] args) {
String pdfUrl = "xxx";
//其他两种根据个人实际需求调整,得到输入流
InputStream inputStream = getInputStream(null, "", pdfUrl);
//传入输入流进行打印,前提是pc安装完成打印机驱动并连接打印机
getPdf(inputStream);
}
public static void getPdf(InputStream inputStream) {
try {
PDDocument document = PDDocument.load(inputStream);
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setJobName("任务名称");
//查找所有的可用打印服务
PrintService[] printServices = PrinterJob.lookupPrintServices();
if (null == printServices || printServices.length == 0) {
throw new Exception("未找到可用打印机,请检查!");
}
//定位默认的打印服务,服务里获取不到
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
if (null == defaultService) {
throw new Exception("未找到默认打印机!");
}
printJob.setPrintService(defaultService);
//设置纸张及缩放
PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.SHRINK_TO_FIT);
//设置多页打印
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);
printJob.print();
document.close();
}catch (Exception e){
e.printStackTrace();
}
}
public static Paper getPaper() {
Paper paper = new Paper();
// 定义毫米到英寸的转换系数,不用变
double mmToInch = 1 / 25.4;
// 定义英寸到点的转换系数,不用变
double inchToPoint = 72;
// 定义纸张尺寸(单位:毫米)这两个值是打印纸张大小,如标准A4纸即210mm×297mm,其他大小纸张自行定义修改
double paperWidthMm = 210;
double paperHeightMm = 297;
// 将纸张尺寸转换为点
double paperWidthPoints = paperWidthMm * mmToInch * inchToPoint;
double paperHeightPoints = paperHeightMm * mmToInch * inchToPoint;
paper.setSize(paperWidthPoints, paperHeightPoints);
//这个x(横向)和y(纵向)是定义打印页边距,根据实际情况调整,可为负数
paper.setImageableArea(0, 0, paperWidthPoints, paperHeightPoints);
return paper;
}
/**
* PDDocument是Apache PDFBox中的一个核心类,它代表一个PDF文档,该方法通过不同的方式
* 构建输入流,来准备创建PDDocument的入参
* @param file 方式一 模拟前端表单提交(接收参数为MultipartFile)
* @param pdfBase64Str 方式二 pdf的base64编码
* @param pdfUrl 方式三 pdf的url链接
* @return
*/
public static InputStream getInputStream(MultipartFile file, String pdfBase64Str, String pdfUrl) {
InputStream inputStream = null;
try {
if (null != file) {
//表单提交
inputStream = file.getInputStream();
}else if(!StringUtils.isEmpty(pdfBase64Str)){
//base64编码
//去掉前面的base64前缀
String dataStr = pdfBase64Str.replace("data:application/pdf;chartset=utf-8;base64,", "")
.replace("data%3Aapplication%2Fpdf%3Bchartset%3Dutf-8%3Bbase64%2C", "");
byte[] data = Base64.decodeBase64(dataStr);
inputStream = new ByteArrayInputStream(data);
}else{
//pdf的url链接
URL u = new URL(pdfUrl);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
DataInputStream in = new DataInputStream(connection.getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int count = 0;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
byte[] pdfBytes = out.toByteArray();
inputStream = new ByteArrayInputStream(pdfBytes);
}
}catch (Exception e){
e.printStackTrace();
}
return inputStream;
}
}