| | |
| | | import com.deepoove.poi.config.ConfigureBuilder; |
| | | import com.deepoove.poi.data.TextRenderData; |
| | | import com.deepoove.poi.data.style.Style; |
| | | import com.google.common.collect.Lists; |
| | | import com.product.common.lang.StringUtils; |
| | | import com.product.core.cache.DataPoolCacheImpl; |
| | | import com.product.core.config.Global; |
| | | import com.product.core.entity.DataEntity; |
| | | import com.product.core.entity.DataTableEntity; |
| | | import com.product.core.entity.FieldSetEntity; |
| | | import com.product.core.exception.BaseException; |
| | |
| | | import com.product.print.config.CmnCode; |
| | | import com.product.print.config.CmnConst; |
| | | import com.product.print.service.ide.IPrintRealizeService; |
| | | import com.product.print.util.CustomPictureRenderPolicy; |
| | | import com.product.print.util.DynamicTableRenderPolicy; |
| | | import com.product.print.util.FlowOpinionRenderPolicy; |
| | | import com.product.print.util.TableEmptyHandler; |
| | | import com.product.tool.flow.service.FlowDetailService; |
| | | import com.product.util.BaseUtil; |
| | | |
| | | import com.product.util.SystemParamReplace; |
| | | import org.apache.pdfbox.io.MemoryUsageSetting; |
| | | import org.apache.pdfbox.multipdf.PDFMergerUtility; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.*; |
| | | import java.io.File; |
| | | import java.io.OutputStream; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | public static void dataConvertCheckedData(FieldSetEntity fse) { |
| | | |
| | | TextRenderData selSymbol = new TextRenderData(CmnConst.PRINT_CHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 14)); |
| | | TextRenderData unselSymbol = new TextRenderData(CmnConst.PRINT_UNCHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 14)); |
| | | TextRenderData unselSymbol = new TextRenderData(CmnConst.PRINT_UNCHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 18)); |
| | | |
| | | //获取表单字段 |
| | | Object[] fields = fse.getMeta().getFields(); |
| | |
| | | /** |
| | | * 打印传输pdf流到前端 |
| | | * |
| | | * @param fse 打印数据 |
| | | * @param fseOrDte 打印数据 |
| | | * @param response 响应 |
| | | * @param isConvertPdf 是否转换为pdf |
| | | * @throws BaseException |
| | | */ |
| | | @Override |
| | | public void print(FieldSetEntity fse, HttpServletResponse response, boolean isConvertPdf) throws BaseException { |
| | | //打印配置 |
| | | FieldSetEntity printConfig = getPrintConfig(fse.getString("~" + CmnConst.PRINT_TEMP + "~")); |
| | | public void print(DataEntity fseOrDte, HttpServletResponse response, boolean isConvertPdf) throws BaseException { |
| | | FieldSetEntity fse; |
| | | DataTableEntity dte; |
| | | //打印配置 |
| | | FieldSetEntity printConfig; |
| | | if (fseOrDte.isFieldsetEntity()) { |
| | | fse = (FieldSetEntity) fseOrDte; |
| | | printConfig = getPrintConfig(getPrintTemplateField(fse)); |
| | | } else if (fseOrDte.isDataTableEntity()) { |
| | | dte = (DataTableEntity) fseOrDte; |
| | | fse = dte.getFieldSetEntity(0); |
| | | printConfig = getPrintConfig(getPrintTemplateField(fse)); |
| | | } else { |
| | | throw new BaseException(CmnCode.GET_BEAN_FAIL); |
| | | } |
| | | //获取到替换后的文件路径 (pdf文件或者word文件) |
| | | String tempPdfFilePath = replaceTemplateFileOut(printConfig, fse, isConvertPdf); |
| | | String tempPdfFilePath = replaceTemplateFileOut(printConfig, fseOrDte, isConvertPdf); |
| | | if (StringUtils.isEmpty(tempPdfFilePath)) { |
| | | throw new BaseException(CmnCode.DEALT_FILE_PATH_IS_EMPTY); |
| | | } |
| | | //获取文件名 |
| | | String fileName = BaseUtil.ifNull(printConfig.getString(CmnConst.PRINT_FILE_NAME), printConfig.getString(CmnConst.PRINT_NAME)); |
| | | if (isConvertPdf) { |
| | |
| | | // 设置自定义头Content-Disposition |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + URLEncodeUtil.encode(fileName)); |
| | | |
| | | try ( |
| | | OutputStream out = response.getOutputStream(); |
| | | ) { |
| | | FileUtil.writeToStream(new File(tempPdfFilePath), out); |
| | | } catch (Exception e) { |
| | | try (OutputStream out = response.getOutputStream();) { |
| | | if (tempPdfFilePath.contains(",")) { |
| | | // 更高效的方式:直接从文件合并到输出流 |
| | | PDFMergerUtility merger = new PDFMergerUtility(); |
| | | merger.setDestinationStream(response.getOutputStream()); |
| | | |
| | | String[] tempPdfFilePathArr = tempPdfFilePath.split(","); |
| | | for (int i = 0; i < tempPdfFilePathArr.length; i++) { |
| | | String singleTempPdfFilePath = tempPdfFilePathArr[i]; |
| | | File file = new File(singleTempPdfFilePath); |
| | | if (file.exists()) { |
| | | merger.addSource(file); // 直接添加文件源 |
| | | } |
| | | } |
| | | |
| | | // 执行合并 |
| | | merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()); |
| | | } else { |
| | | FileUtil.writeToStream(new File(tempPdfFilePath), out); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new BaseException(CmnCode.PRINT_CONTENT_FAIL, e); |
| | | } finally { |
| | | //删除pdf临时文件 |
| | | FileUtil.del(tempPdfFilePath); |
| | | File file = new File(tempPdfFilePath); |
| | | String absolutePath = file.getAbsolutePath(); |
| | | System.out.println(absolutePath); |
| | | file.delete(); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 获取打印模板字段 |
| | | * @param fse |
| | | * @return |
| | | */ |
| | | private String getPrintTemplateField(FieldSetEntity fse) { |
| | | if (FieldSetEntity.isEmpty(fse)) { |
| | | return null; |
| | | } |
| | | String printTemplateField = fse.getString("~" + CmnConst.PRINT_TEMP + "~"); |
| | | if (StringUtils.isEmpty(printTemplateField)) { |
| | | printTemplateField = fse.getString("~print_template~"); |
| | | } |
| | | return printTemplateField; |
| | | } |
| | | |
| | | /** |
| | | * 获取打印配置 |
| | |
| | | * 替换模板文件并输出 |
| | | * |
| | | * @param printConf 打印配置 |
| | | * @param fse 替换数据 |
| | | * @param fseOrDte 替换数据 |
| | | * @param isConvertPdf 是否转换为pdf |
| | | * @return 替换后的文件路径 |
| | | * @throws BaseException 异常 |
| | | */ |
| | | private String replaceTemplateFileOut(FieldSetEntity printConf, FieldSetEntity fse, boolean isConvertPdf) throws BaseException { |
| | | private String replaceTemplateFileOut(FieldSetEntity printConf, DataEntity fseOrDte, boolean isConvertPdf) throws BaseException { |
| | | FieldSetEntity fse = null; |
| | | DataTableEntity dte = null; |
| | | if (fseOrDte.isFieldsetEntity()) { |
| | | fse = (FieldSetEntity) fseOrDte; |
| | | } else if (fseOrDte.isDataTableEntity()) { |
| | | dte = (DataTableEntity) fseOrDte; |
| | | } else { |
| | | throw new BaseException(CmnCode.GET_BEAN_FAIL); |
| | | } |
| | | if (fse != null) { |
| | | dte = new DataTableEntity(); |
| | | dte.addFieldSetEntity(fse); |
| | | } |
| | | |
| | | Object[] fields = fse.getFields(); |
| | | for (int i = 0; i < fields.length; i++) { |
| | | String field = fields[i].toString(); |
| | | FieldSetEntity metaEntity = fse.getMeta().getFieldMeta(field); |
| | | String fieldType = metaEntity.getString("field_type"); |
| | | //判断是否拥有流程标识 |
| | | if ("flowsign".equals(fieldType)) { |
| | | if (StringUtils.equalsAny(fse.getString(field), "1", "2")) { |
| | | //流程办理中或办结 获取流程意见 |
| | | FieldSetEntity flowTask = getBaseDao().getFieldSetByFilter("product_sys_flow_task", "table_name=? and record_uuid=?", new Object[]{fse.getTableName(), fse.getUUID()}, false); |
| | | if (flowTask != null) { |
| | | String taskUuid = flowTask.getString(CmnConst.UUID); |
| | | //获取流程意见 |
| | | FlowDetailService flowDetailService = SpringUtil.getBean(FlowDetailService.class); |
| | | JSONArray opinion = flowDetailService.getHistoryInfo(taskUuid); |
| | | fse.setValue("~flow_opinion~", opinion); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | List<String> localTempPathList = Lists.newArrayList(); |
| | | if (!DataTableEntity.isEmpty(dte)) { |
| | | for (int m = 0; m < dte.getRows(); m++) { |
| | | fse = dte.getFieldSetEntity(m); |
| | | |
| | | // 打印模板附件uuid |
| | | String template_uuid = printConf.getString(CmnConst.PRINT_TEMPLATE); |
| | | // 获取打印模板 |
| | | File file = getTemplateFile(template_uuid); |
| | | // 加载参照 打印时使用显示值 而不是实际值 |
| | | getBaseDao().loadPromptData(fse); |
| | | // 文件名前缀部分 |
| | | Object tempKey = UUID.randomUUID(); |
| | | // 替换后的word临时路径 |
| | | String localTempPathWord = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".docx"; |
| | | replaceWord(localTempPathWord, file.getPath(), fse); |
| | | file.delete(); |
| | | Object[] fields = fse.getFields(); |
| | | for (int i = 0; i < fields.length; i++) { |
| | | String field = fields[i].toString(); |
| | | FieldSetEntity metaEntity = fse.getMeta().getFieldMeta(field); |
| | | if (metaEntity == null) { |
| | | continue; |
| | | } |
| | | String fieldType = metaEntity.getString("field_type"); |
| | | //判断是否拥有流程标识 |
| | | if ("flowsign".equals(fieldType)) { |
| | | if (StringUtils.equalsAny(fse.getString(field), "1", "2")) { |
| | | //流程办理中或办结 获取流程意见 |
| | | FieldSetEntity flowTask = getBaseDao().getFieldSetByFilter("product_sys_flow_task", "table_name=? and record_uuid=?", new Object[]{fse.getTableName(), fse.getUUID()}, false); |
| | | if (flowTask != null) { |
| | | String taskUuid = flowTask.getString(CmnConst.UUID); |
| | | //获取流程意见 |
| | | FlowDetailService flowDetailService = SpringUtil.getBean(FlowDetailService.class); |
| | | JSONArray opinion = flowDetailService.getHistoryInfo(taskUuid); |
| | | fse.setValue("~flow_opinion~", opinion); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | String replaceParams = SystemParamReplace.replaceParams(printConf.getString(CmnConst.PRINT_FILE_NAME), fse); |
| | | printConf.setValue(CmnConst.PRINT_FILE_NAME, replaceParams); |
| | | if (isConvertPdf) { |
| | | try { |
| | | // 替换后的pdf临时路径 |
| | | String localTempPathPdf = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".pdf"; |
| | | //检查文件是否存在不存则创建 |
| | | FileUtil.touch(localTempPathPdf); |
| | | // 转换pdf |
| | | PdfConcurrenceUtil.convertToPdf(localTempPathWord, localTempPathPdf, "docx"); |
| | | // 删除word临时文件 |
| | | File wordTemp = new File(localTempPathWord); |
| | | if (wordTemp.exists()) { |
| | | wordTemp.delete(); |
| | | } |
| | | return localTempPathPdf; |
| | | } catch (Exception e) { |
| | | throw new BaseException(CmnCode.CONVERT_PDF_ERROR, e); |
| | | } finally { |
| | | FileUtil.del(localTempPathWord); |
| | | } |
| | | } |
| | | return localTempPathWord; |
| | | // 打印模板附件uuid |
| | | String template_uuid = printConf.getString(CmnConst.PRINT_TEMPLATE); |
| | | // 获取打印模板 |
| | | File file = getTemplateFile(template_uuid); |
| | | // 加载参照 打印时使用显示值 而不是实际值 |
| | | getBaseDao().loadPromptData(fse); |
| | | // 文件名前缀部分 |
| | | Object tempKey = UUID.randomUUID(); |
| | | // 替换后的word临时路径 |
| | | String localTempPathWord = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".docx"; |
| | | |
| | | replaceWord(localTempPathWord, file.getPath(), fse); |
| | | file.delete(); |
| | | |
| | | String replaceParams = SystemParamReplace.replaceParams(Optional.ofNullable(printConf.getString(CmnConst.PRINT_FILE_NAME)).orElse(printConf.getString(CmnConst.PRINT_NAME)), fse); |
| | | printConf.setValue(CmnConst.PRINT_FILE_NAME, replaceParams); |
| | | if (isConvertPdf) { |
| | | try { |
| | | // 替换后的pdf临时路径 |
| | | String localTempPathPdf = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".pdf"; |
| | | //检查文件是否存在不存则创建 |
| | | FileUtil.touch(localTempPathPdf); |
| | | // 转换pdf |
| | | PdfConcurrenceUtil.convertToPdf(localTempPathWord, localTempPathPdf, "docx"); |
| | | // 删除word临时文件 |
| | | File wordTemp = new File(localTempPathWord); |
| | | if (wordTemp.exists()) { |
| | | wordTemp.delete(); |
| | | } |
| | | localTempPathList.add(localTempPathPdf); |
| | | } catch (Exception e) { |
| | | throw new BaseException(CmnCode.CONVERT_PDF_ERROR, e); |
| | | } finally { |
| | | FileUtil.del(localTempPathWord); |
| | | } |
| | | } else { |
| | | localTempPathList.add(localTempPathWord); |
| | | } |
| | | } |
| | | } |
| | | return BaseUtil.collection2String(localTempPathList); |
| | | } |
| | | |
| | | /** |
| | |
| | | Map<String, Object> cloneValues = new HashMap(dataFse.getValues()); |
| | | //获取子表数据 |
| | | Map<String, DataTableEntity> subDataMap = dataFse.getSubData(); |
| | | ConfigureBuilder config = Configure.createDefault().builder(); |
| | | ConfigureBuilder config = Configure.builder(); |
| | | config.addPlugin('@', new FlowOpinionRenderPolicy(flowOpinion)); |
| | | config.addPlugin('&', new CustomPictureRenderPolicy()); |
| | | config.buildGrammerRegex("(#)?([\\w\\u4e00-\\u9fa5]+)(\\.?[\\w\\u4e00-\\u9fa5\\|]*)*(#)?"); |
| | | TableEmptyHandler tableEmptyHandler = new TableEmptyHandler(); |
| | | if (!CollectionUtil.isEmpty(subDataMap)) { |
| | | for (Map.Entry<String, DataTableEntity> entry : subDataMap.entrySet()) { |
| | | cloneValues.put(entry.getKey(), entry.getValue().getData().stream().map(item -> (Map<String, Object>) ((Map) item.getValues())).collect(Collectors.toList())); |
| | | config.bind(entry.getKey(), new DynamicTableRenderPolicy(entry.getKey())); |
| | | tableEmptyHandler.addTag(entry.getKey()); |
| | | } |
| | | } |
| | | if(flowOpinion!=null && flowOpinion.size()>0){ |
| | | cloneValues.put("lx_flow_opinion", flowOpinion); |
| | | config.bind("lx_flow_opinion", new DynamicTableRenderPolicy("lx_flow_opinion")); |
| | | if (flowOpinion != null) { |
| | | if (!CollectionUtil.isEmpty(flowOpinion)) { |
| | | cloneValues.put("lx_flow_opinion", flowOpinion); |
| | | config.bind("lx_flow_opinion", new DynamicTableRenderPolicy("lx_flow_opinion")); |
| | | } |
| | | tableEmptyHandler.addTag("lx_flow_opinion"); |
| | | } |
| | | config.setValidErrorHandler(tableEmptyHandler); |
| | | |
| | | try { |
| | | //检查输出文件是否存在,不存在则创建 |
| | | FileUtil.touch(outPath); |