/**
生成AI识别数据PDF(新)
@param aiTaskOID AI任务OID
@param response HttpServletResponse对象,用于返回PDF文件流 */ @Override public void pdf(Long aiTaskOID, HttpServletResponse response) { // 定义日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”); SimpleDateFormat dateTimeFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
// 获取AI任务预览数据 AIToPreviewVONew vo = toPreview(aiTaskOID); AIToPreviewTaskVONew task = vo.getTask(); Map
taskTimeResult = task.getTaskTimeResult(); List outcomes = vo.getOutcomes(); try {
// 加载PDF模板文件
ClassPathResource resource = new ClassPathResource("ai/ainew.pdf");
// 创建字节输出流数组,一个用于任务报告,其余用于异常情况报告
ByteArrayOutputStream bos[] = new ByteArrayOutputStream[(CollectionUtils.isEmpty(outcomes) ? 1 : 1 + outcomes.size())];
for (int i = 0; i < bos.length; i++) {
bos[i] = new ByteArrayOutputStream();
// 使用PdfStamper将PDF模板填充为表单,并输出到字节输出流中
PdfReader reader = new PdfReader(resource.getInputStream());
PdfStamper stamper = new PdfStamper(reader, bos[i]);
AcroFields form = stamper.getAcroFields();
// 设置字体为中文字体
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(bfChinese);
if (i == 0) { // 第一个字节输出流用于任务报告
// 填充表单字段
form.setField("AINameCN", task.getTaskName() + "任务报告");
form.setField("reportDate", dateFormat.format(task.getReportDate()));
form.setField("businessRowNO", StringUtils.EMPTY);
form.setField("realTime", StringUtils.EMPTY);
form.setField("position", StringUtils.EMPTY);
form.setField("Text1", "任务名称:");
form.setField("taskName", task.getTaskName());
form.setField("Text4", "任务时长:");
form.setField("taskTime", taskTimeResult.get("hour") + "小时" + taskTimeResult.get("minute") + "分钟" + taskTimeResult.get("second") + "秒");
form.setField("Text2", "开始时间:");
form.setField("startTime", dateTimeFormat.format(task.getStartDateTime()));
form.setField("Text5", "结束时间:");
form.setField("endTime", Objects.isNull(task.getEndDateTime()) ? StringUtils.EMPTY : dateTimeFormat.format(task.getEndDateTime()));
form.setField("Text3", "识别次数:");
form.setField("times", task.getAiOutcomeCount().toString());
form.setField("Text6", "任务长度:");
form.setField("length", task.getTaskDistanceResult() + "千米");
form.setField("timePoint", StringUtils.EMPTY);
form.setField("longitude", StringUtils.EMPTY);
form.setField("abnormalTitle", StringUtils.EMPTY);
form.setField("abnormalTypes", StringUtils.EMPTY);
// 如果没有异常情况,则在表单中显示“本次执行的飞行任务,经过AI智能检测,并未在飞行航线线路上检测到异常情况。此报告仅针对此次飞行任务负责。如有疑问,可通过查看历史直播视频数据进行核对审查!”
if (CollectionUtils.isEmpty(outcomes)) {
form.setField("noData", "本次执行的飞行任务,经过AI智能检测,并未在飞行航线线路上检测到异常情况。此报告仅针对此次飞行任务负责。如有疑问,可通过查看历史直播视频数据进行核对审查!");
} else {
form.setField("noData", StringUtils.EMPTY);
}
} else { // 其余字节输出流用于异常情况报告
AIToPreviewOutcomeVONew outcome = outcomes.get(i - 1);
// 填充表单字段
form.setField("AINameCN", StringUtils.EMPTY);
form.setField("reportDate", StringUtils.EMPTY);
form.setField("businessRowNO", "识别情况(" + i + "):");
// 如果没有实时图像,则不显示实时图像
if (StringUtils.isBlank(outcome.getOutcomeUrl())) {
form.setField("realTime", StringUtils.EMPTY);
} else {
int page = form.getFieldPositions("realTime").get(0).page;
Rectangle signRect = form.getFieldPositions("realTime").get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
Image image = Image.getInstance(outcome.getOutcomeUrl());
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
image.setAbsolutePosition(x, y);
PdfContentByte under = stamper.getOverContent(page);
under.addImage(image);
}
// 如果没有地图图像,则不显示地图图像
if (StringUtils.isBlank(outcome.getMapUrl())) {
form.setField("position", StringUtils.EMPTY);
} else {
int page = form.getFieldPositions("position").get(0).page;
Rectangle signRect = form.getFieldPositions("position").get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
Image image = Image.getInstance(outcome.getMapUrl());
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
image.setAbsolutePosition(x, y);
PdfContentByte under = stamper.getOverContent(page);
under.addImage(image);
}
// 其他字段设为空
form.setField("Text1", StringUtils.EMPTY);
form.setField("taskName", StringUtils.EMPTY);
form.setField("Text4", StringUtils.EMPTY);
form.setField("taskTime", StringUtils.EMPTY);
form.setField("Text2", StringUtils.EMPTY);
form.setField("startTime", StringUtils.EMPTY);
form.setField("Text5", StringUtils.EMPTY);
form.setField("endTime", StringUtils.EMPTY);
form.setField("Text3", StringUtils.EMPTY);
form.setField("times", StringUtils.EMPTY);
form.setField("Text6", StringUtils.EMPTY);
form.setField("length", StringUtils.EMPTY);
// 填充时间点和经纬度等字段
form.setField("timePoint", "时间点:" + dateTimeFormat.format(outcome.getAddDateTime()));
form.setField("longitude", "经纬度:" + outcome.getLongitude() + "," + outcome.getLatitude());
form.setField("abnormalTitle", "识别类型:");
form.setField("abnormalTypes", outcome.getAbnormalLabel());
}
// 将表单设置为不可编辑
stamper.setFormFlattening(true);
stamper.close();
}
// 创建PDF文档对象
Document document = new Document();
// 使用PdfCopy将所有字节输出流合并成一个PDF文件,并输出到response的输出流中
PdfCopy pdfCopy = new PdfCopy(document, response.getOutputStream());
document.open();
for (int i = 0; i < bos.length; i++) {
PdfImportedPage impage = pdfCopy.getImportedPage(new PdfReader(bos[i].toByteArray()), 1);
pdfCopy.addPage(impage);
}
document.close();
// 设置HTTP响应头信息,用于告知浏览器返回的是PDF文件流,以及文件名
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Content-disposition", "formPDF");
response.setHeader("Content-type", "application/pdf;charset=utf-8");
response.setHeader("Content-disposition", "attachment; filename=" + new String((System.currentTimeMillis() + "AI检测报告.pdf").getBytes("UTF-8"), "iso8859-1"));
} catch (Exception e) { // 捕获异常,记录日志,并抛出自定义异常
log.error("生成AI识别数据PDF(新)失败", e);
throw new BaseException(e.getMessage(), e);
} }