0. 效果预览
1. 准备环境
2. Java如何调用打印机进行打印
3. Java如何生成pdf打印文件
4. 实现pdf内数据动态填充(可按需求改变数据,有一个模板就行)
1. java标准开发环境
2. 打印机一台(确保已和设备连接),测试的时候要用,开发没有打印机也行
3. 相关jar包
- pdfbox
- itextpdf
- commons-logging.jar
之前写过一篇,多种方式,有兴趣的可以看看。点击这里查看
这里使用的是PDFBox方式实现打印,引入PDFBox.jar和commons-logging.jar,嫌麻烦地可以在文章底部下载demo,我把所有相关的jar,源码都放进去了
传入文件对象即可进行打印,打印前请确认打印机是否正常连接!!!!
/**
* 打印实现类
* createTime:2018-08-01
*
* @author Jason
*
*/
public final class JHPrintor {
/** 日志记录对象 */
private static Logger log = Logger.getLogger(JHPrintor.class);
/** 私有构造器 */
private JHPrintor() {
}
/**
* 打印pdf文件
*
* @param file 需打印的pdf文件
*/
public static void print(File file) {
try {
PDDocument document = PDDocument.load(file);
// 加载成打印文件
PDFPrintable printable = new PDFPrintable(document,Scaling.ACTUAL_SIZE);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(printable);
job.defaultPage();
job.print();
} catch (InvalidPasswordException e) {
log.error("打印异常:文档初始化密码失败!");
PromptUtil.error("初始化文档密码异常,打印失败!");
e.printStackTrace();
} catch (IOException e) {
log.error("打印异常!");
PromptUtil.error("打印异常,请关闭后重试!");
e.printStackTrace();
} catch (PrinterException e) {
log.error("未正常连接打印机");
PromptUtil.error("请检查打印机是否正常连接!");
e.printStackTrace();
}
}
}
这个比较复杂,涉及到单元格,表,段落,标题等内容
慢慢来,一步一步讲解一下
/**
* 生成pdf文件的工具类
* createTime:2018-08-01
*
* @author Jason
*
*/
public class JHCreatePDF {
// 日志记录对象
public static Logger log = Logger.getLogger(JHCreatePDF.class);
// 系统字体文件在 Windows/Fonts目录下,将其粘到src下即可
public static final String CHARACTOR_FONT_CH_FILE = "/SIMSUN.TTC,1"; //宋体 常规
// 纸张尺寸
public static final Rectangle PAGE_SIZE = PageSize.A4;
// 边距
public static final float MARGIN_LEFT = 50;
public static final float MARGIN_RIGHT = 50;
public static final float MARGIN_TOP = 50;
public static final float MARGIN_BOTTOM = 50;
public static final float SPACING = 20;
// 文件对象
private Document document = null;
private File file;
/**
* 功能:创建导出数据的目标文档
* @return
*/
public void createDocument() {
// 创建pdf文件
FileOutputStream out = null;
document = new Document(PAGE_SIZE, MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM);
try {
file = File.createTempFile("temp", ".pdf");
} catch (IOException e1) {
Log.error("创建临时打印文件失败!");
PromptUtil.error("创建临时打印文件失败,请关闭重试");
e1.printStackTrace();
return; // 结束后续运行
}
try {
out = new FileOutputStream(file);
PdfWriter.getInstance(document, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
// 打开文档准备写入内容
document.open();
}
/**
* 功能 创建PDF文档中的章节
* @param title 章节标题
* @param chapterNum 章节序列号
* @param alignment 0表示align=left,1表示align=center
* @param numberDepth 章节是否带序号 设值=1 表示带序号 1.章节一;1.1小节一...,设值=0表示不带序号
* @param font 字体格式
* @return Chapter章节
*/
public static Chapter createChapter(String title, int chapterNum, int alignment, int numberDepth, Font font) {
Paragraph chapterTitle = new Paragraph(title, font);
chapterTitle.setAlignment(alignment);
Chapter chapter = new Chapter(chapterTitle, chapterNum);
chapter.setNumberDepth(numberDepth);
return chapter;
}
/**
* 功能:创建某指定章节下的小节
* @param chapter 指定章节
* @param title 小节标题
* @param font 字体格式
* @param numberDepth 小节是否带序号 设值=1 表示带序号 1.章节一;1.1小节一...,设值=0表示不带序号
* @return section在指定章节后追加小节
*/
public static Section createSection(Chapter chapter, String title, Font font, int numberDepth) {
Section section = null;
if(chapter != null) {
Paragraph sectionTitle = new Paragraph(title, font);
sectionTitle.setSpacingBefore(SPACING);
section = chapter.addSection(sectionTitle);
section.setNumberDepth(numberDepth);
}
return section;
}
/**
* 功能:向PDF文档添加chunk
*
* @param text
* @param font
* @return
*/
public static Chunk createChunk(String text,Font font) {
return new Chunk(text, font);
}
/**
* 功能:向PDF文档中添加的内容 (核心句子)
* @param text 内容
* @param font 内容对应的字体
* @return phrase 指定字体格式的内容
*/
public static Phrase createPhrase(String text,Font font) {
Phrase phrase = new Paragraph(text,font);
return phrase;
}
/**
* 最后关闭PDF文档
*/
public void closeDocument() {
if(document != null) {
document.close();
}
}
/**
* 读PDF文件,使用了pdfbox开源项目
* @param fileName
*/
public void readPDF(String fileName) {
File file = new File(fileName);
FileInputStream in = null;
try {
in = new FileInputStream(fileName);
// 新建一个PDF解析器对象
PDFParser parser = new PDFParser((RandomAccessRead) in);
// 对PDF文件进行解析
parser.parse();
// 获取解析后得到的PDF文档对象
PDDocument pdfdocument = parser.getPDDocument();
// 新建一个PDF文本剥离器
PDFTextStripper stripper = new PDFTextStripper();
// 从PDF文档对象中剥离文本
String result = stripper.getText(pdfdocument);
System.out.println("PDF文件的文本内容如下:");
System.out.println(result);
} catch (Exception e) {
System.out.println("读取PDF文件" + file.getAbsolutePath() + "生失败!" + e);
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
}
}
}
}
/**
* 获取临时文件
*
* @return
*/
public File getTempFile() {
if(file == null);
log.error("生成的临时文件失败");
return file;
}
}
这是生成pdf的一个工具类,代码注释写的比较详细,直接看就行
主要讲一下需要注意的地方:
文件字体:必须有字体文件
// 系统字体文件在 Windows/Fonts目录下,将其粘到src下即可
public static final String CHARACTOR_FONT_CH_FILE = "/SIMSUN.TTC,1"; //宋体 常规
纸张尺寸:设置A4,有别的需求可自行设置
// 纸张尺寸
public static final Rectangle PAGE_SIZE = PageSize.A4;
上下左右边距:就是文件内容距离上下左右四条边的距离,可自行根据需求设置
// 边距
public static final float MARGIN_LEFT = 50;
public static final float MARGIN_RIGHT = 50;
public static final float MARGIN_TOP = 50;
public static final float MARGIN_BOTTOM = 50;
生成pdf时,必须最先调用方法生成document对象,并向里写数据
void createDocument()
pdf内容写完时,最后调用,关闭document对象
void closeDocument()
private void writeVA(Chapter chapter) {
// -------------------------这里开始 到下面写你自己的数据对象解析逻辑 --------
VisualAcuity[] vaArr = {
leftPreVA,leftSufVA,rightPreVA,rightSufVA,doublePreVA,doubleSufVA} ;
initVA(); // 实例化对象
List<VisualAcuity> vaList = ppe.getVaList();
if (vaList != null&& vaList.size() > 0) {
for (VisualAcuity va:vaList
) {
fillVisualAcuity(va);
}
}
// --------------------------end -------------------------------------
// 表格标题
JHCreatePDF.createSection(chapter,"视锐度:",titleFont,0);
// 生成一个section对象
Section section = JHCreatePDF.createSection(chapter, null, textFont, 0);
// 创建表格对象, 按需求初始化4列
PdfPTable table = new PdfPTable(4);
PdfPCell cell5 = null;
// 第一行 表头
cell5 = new PdfPCell(JHCreatePDF.createPhrase(null,textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setColspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("单字母视锐度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("行字母视锐度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("拥挤字母视锐度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第二行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("左眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setPaddingTop(7);
cell5.setRowspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("填写你的数据”,textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftPreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftPreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第三行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("右眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setPaddingTop(7);
cell5.setRowspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第四行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("双眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setRowspan(2);
cell5.setPaddingTop(7);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("训练后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
table.setWidthPercentage(100); // 填充度,百分百填充
section.add(table);
}
为什么说是动态呢?? 因为这里使用的只是数据对象模型,只要是这种模型,不同数据的对象就会填充不同的数据,生成内容不同的pdf!
整个流程涉及到pdf如何存储,打印,以及销毁!
下面说说我的思路:
我将生成的pdf存放在系统的临时文件夹中
生成下一个打印文件时,定时检测pdf文件数量,然后删除之前生产的pdf文件
到这里,基本打印,生产,数据填充,文件销毁基本写完
下载demo源码,包含所有相关jar包,以及工具类和完整代码
点击这里下载