/**
生成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);
} }