package com.product.print.service; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.data.style.Style; import com.product.common.lang.StringUtils; import com.product.core.cache.DataPoolCacheImpl; import com.product.core.config.Global; import com.product.core.entity.DataTableEntity; import com.product.core.entity.FieldSetEntity; import com.product.core.exception.BaseException; import com.product.core.service.support.AbstractBaseService; import com.product.file.service.FileManagerService; import com.product.file.util.PdfConcurrenceUtil; import com.product.print.config.CmnCode; import com.product.print.config.CmnConst; import com.product.print.service.ide.IPrintRealizeService; import com.product.util.BaseUtil; import com.product.util.SystemParamReplace; import com.product.util.config.SystemParamSet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; /** * @ClassName PrintRealizeService * @Description 打印实现 业务层 * @Author cheng * @Date 2021/12/1 9:50 */ @Service public class PrintRealizeService extends AbstractBaseService implements IPrintRealizeService { @Autowired FileManagerService fileManagerService; /* public static void main(String[] args) { Map t = new HashMap<>(); Integer a = 1; t.put("test", 1); t.put("test2", true); t.put("test3", 0.11); Map cc = (Map) (Map) t; System.out.println(cc); } */ /* public static void main(String[] args) throws Exception { Map map = new HashMap<>(); List> subMapList = new ArrayList<>(); for (int i = 0; i < 5; i++) { Map subMap = new HashMap<>(); subMap.put("a1", "品名——" + (i + 1)); subMap.put("a2", "单位——" + (i + 1)); subMap.put("a3", "数量——" + (i + 1)); subMap.put("a4", "用途——" + (i + 1)); subMapList.add(subMap); } map.put("BGYPLYB_SUB", subMapList); HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();//创建一个列表的规则 Configure config = Configure.newBuilder().customPolicy("BGYPLYB_SUB", policy).customPolicy("test_table", policy).build(); File targetFile = new File("C:\\Users\\cheng\\Desktop\\replaceWord.docx"); File file = new File("C:\\Users\\cheng\\Desktop\\办公用品领用表.docx"); if (targetFile.exists()) { targetFile.delete(); } targetFile.createNewFile(); try (FileOutputStream is = new FileOutputStream(targetFile); ) { XWPFTemplate render = XWPFTemplate.compile(file, config).render(map); render.write(is); render.close(); } } */ /** * word打印复选框处理 * @param fs */ 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)); //获取表单字段 Object[] fields = fse.getMeta().getFields(); if (fields != null) { for(int i = 0; i < fields.length; ++i) { //获取保存的数据值 String dataSaveValue = fse.getString(fields[i] + CmnConst._SAVE_VALUE); if (!BaseUtil.strIsNull(dataSaveValue)) { //获取每个字段的meta信息 FieldSetEntity meta = fse.getMeta().getFieldMeta(fields[i].toString()); if (meta != null && meta.getString(CmnConst.FIELD_REFERECE) != null && meta.getString(CmnConst.FIELD_REFERECE).indexOf("《")>-1) { //数据对应参照信息 DataTableEntity dictInfos = getMetaAndCacheDictInfo(meta); if (!BaseUtil.dataTableIsEmpty(dictInfos)) { for (int j = 0; j < dictInfos.getRows(); j++) { //获取每个参照对应值 String dict_value = dictInfos.getFieldSetEntity(j).getString(CmnConst.DICT_VALUE); if (dataSaveValue.indexOf(dict_value)>-1) { fse.setValue(fields[i]+"_" + dict_value, selSymbol); }else { fse.setValue(fields[i]+"_" + dict_value, unselSymbol); } } } } } } } } /** * 获取字段对应数据字典信息 * @param fieldMate * @return */ public static DataTableEntity getMetaAndCacheDictInfo(FieldSetEntity fieldMate) { if (fieldMate != null && fieldMate.getString(CmnConst.FIELD_REFERECE) != null) { int a = fieldMate.getString(CmnConst.FIELD_REFERECE).indexOf("《"); int b = fieldMate.getString(CmnConst.FIELD_REFERECE).indexOf("》"); if (b > 1 && a == 0) { return DataPoolCacheImpl.getInstance().getCacheData("数据字典配置信息", new String[]{fieldMate.getString(CmnConst.FIELD_REFERECE).substring(a + 1, b)}); } } return null; } @Override public void printWord(FieldSetEntity fse, HttpServletResponse response) throws BaseException { // 打印配置uuid String print_uuid = fse.getString("~" + CmnConst.PRINT_TEMP + "~"); //查询打印配置 FieldSetEntity fieldSetEntity = getBaseDao().getFieldSetEntity(CmnConst.TABLE_PRINT_CONFIG, print_uuid, false); if (fieldSetEntity == null || StringUtils.isEmpty(fieldSetEntity.getString(CmnConst.PRINT_TEMPLATE))) { throw new BaseException(CmnCode.PRINT_CONFIG_NOT_EXIST.getValue(), CmnCode.PRINT_CONFIG_NOT_EXIST.getText()); } // 打印模板附件uuid String template_uuid = fieldSetEntity.getString(CmnConst.PRINT_TEMPLATE); // 获取打印模板 File file = getFile(template_uuid); // 加载参照 打印时使用显示值 而不是实际值 getBaseDao().loadPromptData(fse); // 文件名前缀部分 Object tempKey = UUID.randomUUID(); // 替换后的word临时路径 String localTempPathWord = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".docx"; File wordTemp = new File(localTempPathWord); try { new File(Global.getSystemConfig("temp.dir", "")).mkdirs(); wordTemp.createNewFile(); } catch (Exception e) { e.printStackTrace(); throw new BaseException(CmnCode.PRINT_CONTENT_FAIL.getValue(), CmnCode.PRINT_CONTENT_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } //将模和当前fse的values放入进行替换 try (FileOutputStream is = new FileOutputStream(wordTemp); OutputStream out = response.getOutputStream()) { Map subData = fse.getSubData(); Configure.ConfigureBuilder configureBuilder = null; if (subData != null && subData.size() > 0) { for (Map.Entry vv : subData.entrySet()) { getBaseDao().loadPromptData(vv.getValue()); if (!DataTableEntity.isEmpty(vv.getValue())) { List collect = vv.getValue().getData().stream().map(item -> (Map) ((Map) item.getValues())).collect(Collectors.toList()); fse.setValue(vv.getKey(), collect); } else { fse.setValue(vv.getKey(), new ArrayList<>()); } if (configureBuilder == null) { configureBuilder = Configure.newBuilder(); } configureBuilder.customPolicy(vv.getKey(), new HackLoopTableRenderPolicy()); } } //复选框处理 dataConvertCheckedData(fse); XWPFTemplate render = XWPFTemplate.compile(file, configureBuilder == null ? Configure.createDefault() : configureBuilder.build()).render(fse.getValues()); render.write(is); render.close(); response.setContentType("multipart/form-data"); response.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有 //设置响应 response.setContentType("application/octet-stream;charset=UTF-8"); // 将响应头中的Content-Disposition暴露出来,不然前端获取不到 response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); String fileName = null; if(!BaseUtil.strIsNull(fieldSetEntity.getString(CmnConst.PRINT_FILE_NAME))) { fileName = SystemParamReplace.replaceParams(fieldSetEntity.getString(CmnConst.PRINT_FILE_NAME), fse); }else { fileName = fieldSetEntity.getString(CmnConst.PRINT_NAME); } fileName+=".docx"; // 在响应头中的Content-Disposition里设置文件名称 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); InputStream isPdf = new FileInputStream(wordTemp); int len; byte[] b = new byte[1024]; // 输出 while ((len = isPdf.read(b)) > 0) { out.write(b, 0, len); } isPdf.close(); } catch (Exception e) { e.printStackTrace(); throw new BaseException(CmnCode.PRINT_CONTENT_FAIL.getValue(), CmnCode.PRINT_CONTENT_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } finally { //删除word临时文件 if (wordTemp.exists()) { System.out.println(wordTemp.getPath()); // wordTemp.delete(); } if (file != null) { file.delete(); } } } @Override public void print(FieldSetEntity fse, HttpServletResponse response) throws BaseException { // 打印配置uuid String print_uuid = fse.getString("~" + CmnConst.PRINT_TEMP + "~"); //查询打印配置 FieldSetEntity fieldSetEntity = getBaseDao().getFieldSetEntity(CmnConst.TABLE_PRINT_CONFIG, print_uuid, false); if (fieldSetEntity == null || StringUtils.isEmpty(fieldSetEntity.getString(CmnConst.PRINT_TEMPLATE))) { throw new BaseException(CmnCode.PRINT_CONFIG_NOT_EXIST.getValue(), CmnCode.PRINT_CONFIG_NOT_EXIST.getText()); } // 打印模板附件uuid String template_uuid = fieldSetEntity.getString(CmnConst.PRINT_TEMPLATE); // 获取打印模板 File file = getFile(template_uuid); // 加载参照 打印时使用显示值 而不是实际值 getBaseDao().loadPromptData(fse); // 文件名前缀部分 Object tempKey = UUID.randomUUID(); // 替换后的word临时路径 String localTempPathWord = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".docx"; // 转换pdf的临时路径 String localTempPathPdf = Global.getSystemConfig("temp.dir", "") + File.separator + "temp_print_" + tempKey + ".pdf"; File wordTemp = new File(localTempPathWord); File pdfTemp = null; try { new File(Global.getSystemConfig("temp.dir", "")).mkdirs(); wordTemp.createNewFile(); } catch (Exception e) { e.printStackTrace(); throw new BaseException(CmnCode.PRINT_CONTENT_FAIL.getValue(), CmnCode.PRINT_CONTENT_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } //将模和当前fse的values放入进行替换 try (FileOutputStream is = new FileOutputStream(wordTemp); OutputStream out = response.getOutputStream()) { Map subData = fse.getSubData(); Configure.ConfigureBuilder configureBuilder = null; if (subData != null && subData.size() > 0) { for (Map.Entry vv : subData.entrySet()) { getBaseDao().loadPromptData(vv.getValue()); if (!DataTableEntity.isEmpty(vv.getValue())) { List collect = vv.getValue().getData().stream().map(item -> (Map) ((Map) item.getValues())).collect(Collectors.toList()); fse.setValue(vv.getKey(), collect); } else { fse.setValue(vv.getKey(), new ArrayList<>()); } if (configureBuilder == null) { configureBuilder = Configure.newBuilder(); } configureBuilder.customPolicy(vv.getKey(), new HackLoopTableRenderPolicy()); } } XWPFTemplate render = XWPFTemplate.compile(file, configureBuilder == null ? Configure.createDefault() : configureBuilder.build()).render(fse.getValues()); render.write(is); render.close(); response.setContentType("multipart/form-data"); response.setHeader("Content-Disposition", "attachment;"); // 使用openOffice 转换为pdf pdfTemp = PdfConcurrenceUtil.convertToPdf(wordTemp.getPath(), localTempPathPdf,"docx"); InputStream isPdf = new FileInputStream(pdfTemp); int len; byte[] b = new byte[1024]; // 输出 while ((len = isPdf.read(b)) > 0) { out.write(b, 0, len); } isPdf.close(); } catch (Exception e) { e.printStackTrace(); throw new BaseException(CmnCode.PRINT_CONTENT_FAIL.getValue(), CmnCode.PRINT_CONTENT_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } finally { // 删除临时文件 if (pdfTemp != null && pdfTemp.exists()) { pdfTemp.delete(); } if (wordTemp.exists()) { wordTemp.delete(); } if (file != null) { file.delete(); } } } private File getFile(String template_uuid) throws BaseException { try { return fileManagerService.getFile(template_uuid); } catch (BaseException e) { e.printStackTrace(); //获取打印模板错误 throw new BaseException(CmnCode.GET_PRINT_TEMPLATE_FILE_FAIL.getValue(), CmnCode.GET_PRINT_TEMPLATE_FILE_FAIL.getText()); } } }