直接上代码:
/**
* 导出pdf
*
* @param subjCode
*/
@GetMapping("/export_pdf")
public void exportPdf(HttpServletResponse response, String[] subjCode) throws IOException {
byte[] data = trainCurricuLumService.exportPdf(subjCode);
genCode(response, data);
}
/**
* 生成zip文件
*/
private void genCode(HttpServletResponse response, byte[] data) throws IOException {
String fileName = DateUtil.getTimeMillis() + ".zip";
fileName = URLEncoder.encode(fileName, "UTF-8");
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
业务逻辑处理
@Override
public byte[] exportPdf(String[] subjCode) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
for (String code : subjCode) {
generatorCode(code, zip);
}
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}
@SneakyThrows
private void generatorCode(String subjCode, ZipOutputStream zip) {
TrainCurricuLum trainCurricuLum = 根据subjCode查询数据库
PeiXuAllVo peiXuAllVo = 根据subjCode查询数据库
TrainRecord trainRecord = new TrainRecord(subjCode);
List<PeiXunDaoVo> list = 根据subjCode查询数据库
//创建Document 对象
Document document = new Document();
document.setPageSize(PageSize.A4);// 设置页面大小
// 使用语言包字体
BaseFont abf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//换行
//document.newPage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, baos);
String curricuLum = trainCurricuLum.getCurricuLum();
if (StringUtils.isNotEmpty(trainCurricuLum.getComName())) {
curricuLum = trainCurricuLum.getComName() + "-" + curricuLum;
}
//设置水印 页码
writer.setPageEvent(new PdfPageHelper(curricuLum));
//打开 pdf
document.open();
//字体
Font font = new Font(abf, 9);
//段落
Paragraph p = new Paragraph(curricuLum, new Font(abf, 14, Font.BOLD));
p.setAlignment(Paragraph.ALIGN_CENTER);
document.add(p);
Phrase tPhrase = new Phrase();
tPhrase.add(Chunk.NEWLINE);// 放在容器中好用
tPhrase.setLeading(14f);// 行间距
document.add(tPhrase);
//表格
//numcolumns:列数
PdfPTable table = new PdfPTable(12);
//表格与上面段落的空隙
table.setSpacingBefore(10f);
//设置表格宽度比例为%100
table.setWidthPercentage(100);
// 设置表格的宽度
table.setTotalWidth(500);
PdfPCell cell = new PdfPCell(new Phrase("培训内容", font));
//垂直居中
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
//水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(3);
table.addCell(cell);
StringBuffer str = new StringBuffer();
trainCurricuLum.getTrainCourseWareList().forEach(trainCourseWare -> {
if (StringUtils.isNotEmpty(str)) {
str.append(", " + trainCourseWare.getCourseWare());
} else {
str.append(trainCourseWare.getCourseWare());
}
});
cell = new PdfPCell(new Phrase(str.toString(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(9);
table.addCell(cell);
//公司名称
cell = new PdfPCell(new Phrase("公司名称: " + trainCurricuLum.getComName(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
cell = new PdfPCell(new Phrase("培训名称: " + trainCurricuLum.getCurricuLum(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
//安全管理员
String compereName = trainCurricuLum.getCompereName();
if (StringUtils.isEmpty(compereName)) {
compereName = "暂无";
}
cell = new PdfPCell(new Phrase("安全管理员: " + compereName, font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
//第三行
cell = new PdfPCell(new Phrase("培训要求: " + trainCurricuLum.getDuraTion() + "学时(" + (trainCurricuLum.getTotalDuration() / 60) + "分)", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
cell = new PdfPCell(new Phrase("考试要求: " + (trainCurricuLum.getAssessMethod().equals("1") ? "无考核" : "考核"), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
Date learningPer = trainCurricuLum.getLearningPer();
String strLearningPer = null;
if (learningPer == null) {
strLearningPer = "暂无";
} else {
strLearningPer = DateUtil.dateToStringDate(learningPer);
}
Date getLearningEnd = trainCurricuLum.getLearningEnd();
String strLearningEnd = null;
if (getLearningEnd == null) {
strLearningEnd = "暂无";
} else {
strLearningEnd = DateUtil.dateToStringDate(getLearningEnd);
}
cell = new PdfPCell(new Phrase("培训截至日期: " + (strLearningPer + "至" + strLearningEnd), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(4);
table.addCell(cell);
//第四行
cell = new PdfPCell(new Phrase("总人数: " + peiXuAllVo.getZongRen() + "(人)", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(3);
table.addCell(cell);
cell = new PdfPCell(new Phrase("已完成: " + peiXuAllVo.getYiWan() + "(人)", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(3);
table.addCell(cell);
cell = new PdfPCell(new Phrase("未完成: " + peiXuAllVo.getWeiWan() + "(人)", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(3);
table.addCell(cell);
cell = new PdfPCell(new Phrase("完成率: " + peiXuAllVo.getSop() + "%", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(3);
table.addCell(cell);
cell = new PdfPCell(new Phrase("各人员完成情况", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(12);
table.addCell(cell);
//动态列
cell = new PdfPCell(new Phrase("序号", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
cell = new PdfPCell(new Phrase("姓名", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
cell = new PdfPCell(new Phrase("身份证号", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
if (trainCurricuLum.getAssessMethod().equals("1")) {
cell = new PdfPCell(new Phrase("岗位", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
} else {
cell = new PdfPCell(new Phrase("岗位", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
}
cell = new PdfPCell(new Phrase("完成情况", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
cell = new PdfPCell(new Phrase("完成进度", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
if (trainCurricuLum.getAssessMethod().equals("2")) {
cell = new PdfPCell(new Phrase("考核结果", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
}
cell = new PdfPCell(new Phrase("状态", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
cell = new PdfPCell(new Phrase("签名照片", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
int size = list.size();
for (int i = 0; i < size; i++) {
PeiXunDaoVo peiXunDaoVo = list.get(i);
cell = new PdfPCell(new Phrase(String.valueOf(i + 1), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
//人员习姓名
cell = new PdfPCell(new Phrase(peiXunDaoVo.getOwnerName(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
//身份证号
cell = new PdfPCell(new Phrase(peiXunDaoVo.getIdCad(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
//岗位
if (trainCurricuLum.getAssessMethod().equals("1")) {
cell = new PdfPCell(new Phrase("驾驶员", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
} else {
cell = new PdfPCell(new Phrase("驾驶员", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
}
//完成情况
BigDecimal bigDecimal1 = new BigDecimal(peiXunDaoVo.getLengthOfStudy());
cell = new PdfPCell(new Phrase("培训时长:" + div(bigDecimal1, new BigDecimal("60")).setScale(0, BigDecimal.ROUND_DOWN).toString() + "分", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(2);
table.addCell(cell);
//已完成进度
BigDecimal bigDecimal2 = new BigDecimal(peiXunDaoVo.getTotalDuration());
BigDecimal bigDecimal = div(bigDecimal1, bigDecimal2).setScale(2, BigDecimal.ROUND_DOWN);
cell = new PdfPCell(new Phrase(BigDecimalUtil.mul(bigDecimal, new BigDecimal("100")) + "%", font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
if (trainCurricuLum.getAssessMethod().equals("2")) {
String exaResults = peiXunDaoVo.getExaResults();
if (StringUtils.isNotEmpty(exaResults)){
cell = new PdfPCell(new Phrase(exaResults.equals("1")?"及格":"未及格", font));
}else{
cell = new PdfPCell(new Phrase("", font));
}
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
}
//状态
cell = new PdfPCell(new Phrase(peiXunDaoVo.getRecordState(), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setFixedHeight(23f);
cell.setColspan(1);
table.addCell(cell);
//签名照
if (StringUtils.isNotEmpty(peiXunDaoVo.getPhoto3())) {
Image image = loadingPicture(peiXunDaoVo.getPhoto3());
table.addCell(image);
} else {
table.addCell("暂无");
}
}
//重点 将数据库添加到pdf
document.add(table);
document.close();
writer.close();
String fileName = curricuLum + ".pdf";
//fileName = URLEncoder.encode(fileName, "UTF-8");
zip.putNextEntry(new ZipEntry(fileName));
byte[] bytes = baos.toByteArray();
zip.write(bytes, 0, bytes.length);
zip.flush();
zip.closeEntry();
}
/**
* 查询图片组装image
*
* @param url
* @return
* @throws IOException
*/
@SneakyThrows
private Image loadingPicture(String url) throws IOException {
byte[] imageFromURL = UrlUtil.getImageFromURL(url);
Image image = Image.getInstance(imageFromURL);
image.scaleAbsolute(60, 20);// 调整图片大小(宽度 高度)
return image;
}
将在线的图片转数组
/**
* 将在线url 转字节
*
* @param urlPath
* @return
*/
public static byte[] getImageFromURL(String urlPath) {
byte[] data = null;
InputStream is = null;
HttpURLConnection conn = null;
try {
URL url = new URL(urlPath);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
// conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setConnectTimeout(6000);
is = conn.getInputStream();
if (conn.getResponseCode() == 200) {
data = readInputStream(is);
} else {
data = null;
}
} catch (MalformedURLException e) {
logger.error("MalformedURLException", e);
} catch (IOException e) {
logger.error("IOException", e);
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.error("IOException", e);
}
conn.disconnect();
}
return data;
}
public static byte[] readInputStream(InputStream is) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = -1;
try {
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
baos.flush();
} catch (IOException e) {
logger.error("IOException", e);
}
byte[] data = baos.toByteArray();
try {
is.close();
baos.close();
} catch (IOException e) {
logger.error("IOException", e);
}
return data;
}
}
分页水印
public class PdfPageHelper extends PdfPageEventHelper {
private PdfTemplate tpl;
private BaseFont bf;
private String shuiyin;
public PdfPageHelper(String shuiyin) {
this.shuiyin = shuiyin;
}
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
tpl = writer.getDirectContent().createTemplate(100, 100);
try {
// bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
@Override
public void onStartPage(PdfWriter writer, Document document) {
super.onStartPage(writer, document);
addTextWaterMark(writer, bf, 18, 0.1f, shuiyin);
//addImageWaterMark(writer, 0.5f, "C:\\Users\\xxx\\Desktop\\waterMark.png");
}
/**
* 重写PdfPageEventHelper中的onEndPage方法
*/
@Override
public void onEndPage(PdfWriter writer, Document document) {
// 新建获得用户页面文本和图片内容位置的对象
PdfContentByte pdfContentByte = writer.getDirectContent();
// 保存图形状态
pdfContentByte.saveState();
// String text = writer.getPageNumber() + "/";
String text = "第 " + writer.getPageNumber() + " 页";
// 获取点字符串的宽度
float textSize = bf.getWidthPoint(text, 9);
pdfContentByte.beginText();
// 设置随后的文本内容写作的字体和字号
pdfContentByte.setFontAndSize(bf, 9);
// 定位'X/'
float x = (document.right() + document.left()) / 2;
//float x = document.right();
float y = 20f;
pdfContentByte.setTextMatrix(x, y);
pdfContentByte.showText(text);
pdfContentByte.endText();
// 将模板加入到内容(content)中- // 定位'Y'
pdfContentByte.addTemplate(tpl, x + textSize, y);
pdfContentByte.restoreState();
}
/* @Override
public void onEndPage(PdfWriter writer, Document document) {
//每一次在页面写完结束后,计算一下页码,
PdfContentByte cb = writer.getDirectContent();
String text = "第 " + writer.getPageNumber() + " 页,共";
float textSize = bf.getWidthPoint(text, 7);
float textBase = document.bottom();
cb.beginText();
cb.setFontAndSize(bf, 8);
cb.setTextMatrix(document.left(), textBase);
cb.showText(text);
cb.endText();
cb.addTemplate(tpl, document.left() + textSize, textBase);
}*/
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
// tpl.beginText();
// tpl.setFontAndSize(bf, 10);
// tpl.setTextMatrix(0, 0);
// // 设置总页数的值到模板上,并应用到每个界面
// tpl.showText(writer.getPageNumber() + " 页");
// tpl.endText();
/* //文档关闭后,计算一下总页数
tpl.beginText();
tpl.setFontAndSize(bf, 8);
tpl.setTextMatrix(0, 0);
tpl.showText(writer.getPageNumber() + " 页");
tpl.endText();*/
}
//文字水印
private static void addTextWaterMark(PdfWriter pdfWriter, BaseFont bf, int fontSize, float fillOpacity, String text) {
//添加水印
PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
contentUnder.beginText();
contentUnder.setColorFill(BaseColor.BLUE);
contentUnder.setFontAndSize(bf, fontSize);
//设置水印透明度
PdfGState pdfGState = new PdfGState();
pdfGState.setFillOpacity(fillOpacity);
contentUnder.setGState(pdfGState);
Random random = new Random();
for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 30; initX += 300) {
for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 30; initY += 250) {
contentUnder.showTextAligned(Element.ALIGN_MIDDLE, text, initX, initY, 30);
}
}
// for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 30; initX += 300) {
// for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 30; initY += 250) {
// contentUnder.showTextAligned(Element.ALIGN_CENTER, text, initX, initY, 30);
// }
// }
contentUnder.endText();
}
//图像水印
private static void addImageWaterMark(PdfWriter pdfWriter, float fillOpacity, String imgUrl) {
PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
try {
Image image = Image.getInstance(imgUrl);
image.scaleToFit(200, 150);
PdfGState pdfGState = new PdfGState();
pdfGState.setFillOpacity(fillOpacity);
contentUnder.setGState(pdfGState);
Random random = new Random();
for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 40; initX += 300) {
for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 40; initY += 300) {
image.setAbsolutePosition(initX, initY);
image.setRotationDegrees(30);
contentUnder.addImage(image);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}