/** @param args */ public static void main(String[] args) { WfVersionBO version = new WfVersionBO(); String processId = "jxstar2"; Map<String, String> mpUser = FactoryUtil.newMap(); mpUser.put("user_id", "administrator"); mpUser.put("user_name", "东宏"); version.newVersion(processId, mpUser); }
/** * 取统计字段 * * @param lsField -- 所有字段信息 * @return */ private static List<Map<String, String>> getStatField(List<Map<String, String>> lsField) { List<Map<String, String>> lsRet = FactoryUtil.newList(); if (lsField == null) return lsRet; Map<String, String> mpField = null; String isstat = null; for (int i = 0, n = lsField.size(); i < n; i++) { mpField = lsField.get(i); isstat = mpField.get("is_stat"); if (isstat.trim().equals("1")) lsRet.add(mpField); } return lsRet; }
/** * 生成公告阅读记录 * * @param msgId -- 消息ID * @param userId -- 用户ID * @param userName -- 用户名 * @return */ public String readBoard(String msgId, String userId, String userName) { Map<String, String> mpRead = FactoryUtil.newMap(); mpRead.put("msg_id", msgId); mpRead.put("user_id", userId); mpRead.put("user_name", userName); mpRead.put("read_date", DateUtil.getTodaySec()); String readId = DmDao.insert("plet_read", mpRead); if (readId == null || readId.length() == 0) { // "生成公告阅读记录失败!" setMessage(JsMessage.getValue("portlet.createboarderror")); return _returnFaild; } return _returnSuccess; }
/** * 取表单中的所有图片元素。 * * @param sheet -- 表单对象 * @return */ private static List<HSSFPicture> getAllPicture(HSSFSheet sheet) { List<HSSFPicture> lsPicture = FactoryUtil.newList(); HSSFPatriarch draw = sheet.getDrawingPatriarch(); if (draw == null) return lsPicture; // 取所有子图形位置 List<HSSFShape> lsShape = draw.getChildren(); if (lsShape == null || lsShape.isEmpty()) return lsPicture; for (int i = 0, n = lsShape.size(); i < n; i++) { HSSFShape shape = lsShape.get(i); if (shape instanceof HSSFPicture) { lsPicture.add((HSSFPicture) shape); } } return lsPicture; }
/** * 复制来源表格中第1个SHEET中的图片到目标表格中的第1个SHEET中。 * * @param destBook -- 目标表格 * @param srcBook -- 来源表格 */ private static void copySheetImage(HSSFWorkbook destBook, HSSFWorkbook srcBook) { // 来源表单 HSSFSheet srcSheet = srcBook.getSheetAt(0); // 目标表单 HSSFSheet destSheet = destBook.getSheetAt(0); // 需要偏移的行数 int endRowNum = destSheet.getPhysicalNumberOfRows(); // 取来源表单中的图片对象 List<HSSFPicture> lsSrcPicture = getAllPicture(srcSheet); _log.showDebug("----------source picture size:" + lsSrcPicture.size()); // 取所有子图形数据,如果是主从报表且明细数据占多页时,则会报空指针错误 List<HSSFPictureData> lsPicData = null; try { lsPicData = srcBook.getAllPictures(); } catch (Exception e) { // e.printStackTrace(); _log.showWarn("由于表单明细有多页,造成临时表的图片数据取不到,只能采用原表第1个图替代!"); // 原表中也没有图片,则不处理图片复制了 lsPicData = destBook.getAllPictures(); if (lsPicData == null || lsPicData.isEmpty()) return; // 只取原表中第1个图片信息 List<HSSFPictureData> destData = FactoryUtil.newList(); for (int i = 0, n = lsSrcPicture.size(); i < n; i++) { destData.add(lsPicData.get(0)); } lsPicData = destData; } if (lsPicData == null || lsPicData.isEmpty()) return; _log.showDebug("----------source data size:" + lsPicData.size()); // data数量可能大于图片数量 if (lsSrcPicture.size() > lsPicData.size()) { _log.showWarn("图片数量与数据数量不符!"); return; } // 取图片管理器 HSSFPatriarch destDraw = destSheet.getDrawingPatriarch(); if (destDraw == null) { destDraw = destSheet.createDrawingPatriarch(); } // 取原目标表单中的图片对象 List<HSSFPicture> lsDestPicture = getAllPicture(destSheet); int index = lsDestPicture.size(); for (int i = 0, n = lsSrcPicture.size(); i < n; i++) { // 取图片对象 HSSFPicture picture = lsSrcPicture.get(i); // 根据图片序号取图片数据 HSSFPictureData picdata = lsPicData.get(i); // 取图片字节信息 byte[] datas = picdata.getData(); // 取图片位置信息 HSSFClientAnchor anchor = (HSSFClientAnchor) picture.getAnchor(); // 添加行偏移值 anchor.setRow1(anchor.getRow1() + endRowNum); anchor.setRow2(anchor.getRow2() + endRowNum); // 插入新图片,返回的新图片序号无效 destBook.addPicture(datas, picdata.getFormat()); // 上面代码中新建图片的序号没有考虑原有图片数量,所以取原图片数量+1作为新图片的序号 index++; _log.showDebug("---------copy new image index=" + index); destDraw.createPicture(anchor, index); } }
/** * 填充数据到表格对象。 * * @param sheet -- 表格对象 * @param lsData -- 输出数据记录 * @param lsField -- 输出字段明细 * @param pageSize -- 每页显示行数 * @param pos -- 开始输出行数 * @param curPage -- 当前是第几页 * @param sumPage -- 总页数 * @return */ public static HSSFSheet fillGrid( HSSFSheet sheet, List<Map<String, String>> lsData, List<Map<String, String>> lsField, int pageSize, int pos, int curPage, int sumPage) { if (lsField == null || lsData == null) { _log.showWarn("data is null or field is null!"); return sheet; } if (lsField.isEmpty() || lsData.isEmpty()) { _log.showDebug("data is empty or field is null!"); return sheet; } HSSFRow row = null; // excel的行对象 HSSFCell cell = null; // excel的列对象 String strValue = null; // 每个格的信息内容 Map<String, String> mpData = null; // 每条记录数据 Map<String, String> mpField = null; // 每条个字段的信息 // HSSFCellStyle style = null; //excel单元格风格对象 int posi = (pageSize > 0 && pos >= 0) ? pos : 0; int cnt = (pageSize <= 0) ? lsData.size() : pageSize + posi; int[] posis = new int[2]; int index = 0, rowIndex = 0; int currRow = 0; int cntCol = 1; // 合计列的位置 String strStyle = null, strColName = null, strColCode = null, strColTag = null; // 用于每页小计 List<Map<String, String>> lsStatCol = getStatField(lsField); String isOutZero = "0"; Map<String, String> mpStat = null, mpStatValue = FactoryUtil.newMap(); String strCol = null; BigDecimal bdStat = null; boolean isStatCol = false; // 用于每页小计 for (rowIndex = posi, index = 0; rowIndex < cnt; rowIndex++, index++) { if (lsData.size() <= rowIndex) break; // 如果rowIndex大于记录数 mpData = lsData.get(rowIndex); for (int i = 0, n = lsField.size(); i < n; i++) { mpField = lsField.get(i); isOutZero = mpField.get("is_outzero"); if (isOutZero == null) isOutZero = "1"; strStyle = mpField.get("format"); // 字段格式 strColName = mpField.get("display"); // 字段名称 strColCode = mpField.get("col_code").toLowerCase(); // 字段编码 strColTag = mpField.get("combo_code"); // 标签 posis = getPosition(mpField.get("col_pos")); if (posis.length != 2) { _log.showWarn(strColName + " [" + mpField.get("col_pos") + "] position is error!"); continue; } // _log.showDebug("col_code=" + strColCode + " col_pos=" + posis); row = sheet.getRow(posis[0] + index); currRow = posis[0] + index; if (row == null) row = sheet.createRow(posis[0] + index); cell = row.getCell(posis[1]); if (cell == null) cell = row.createCell(posis[1]); if (strColCode.equalsIgnoreCase("{CURUSERNAME}")) { // 当前用户 if (_mpUser != null) strValue = _mpUser.get("user_name"); else strValue = ""; } else if (strColCode.equalsIgnoreCase("{CURDATE}")) { // 当前日期 strValue = DateUtil.getToday(); } else if (strColCode.equalsIgnoreCase("{CURDEPTNAME}")) { // 当前部门 if (_mpUser != null) strValue = _mpUser.get("dept_name"); else strValue = ""; } else if (strColCode.equalsIgnoreCase("{NUMBER}")) { // 输出序号 strValue = Integer.toString(rowIndex + 1); cntCol = (short) posis[1]; } else if (strColCode.equalsIgnoreCase("{CURPAGENUM}")) { // 当前所在页数 strValue = Integer.toString(curPage); } else if (strColCode.equalsIgnoreCase("{CURSUMPAGE}")) { // 当前共页数 strValue = Integer.toString(sumPage); } else { // 设置cell的显示值 strValue = mpData.get(strColCode); // 如果已经设置了0值不输出,并且当前值就是0,则输出空字符串 strValue = (strValue != null) ? strValue : ""; strValue = (strValue.equalsIgnoreCase("null")) ? "" : strValue; // 真实值与显示值 strValue = getComboTitle(strValue, strColTag); // 转换数据格式 strValue = convertValue(strValue, strStyle); if (isOutZero.equals("0")) strValue = getZeroOut(strValue, strStyle); } cell.setCellValue(strValue.trim()); if (!lsStatCol.isEmpty()) { for (int iStat = 0, statNum = lsStatCol.size(); iStat < statNum; iStat++) { mpStat = lsStatCol.get(iStat); // _log.showDebug("mpStat = " + mpStat.toString()); if (mpStat.isEmpty()) continue; strCol = (mpStat.get("col_code")).toLowerCase(); // _log.showDebug("strCol = " + strCol + " | strValue = " + strValue); if (strColCode.equalsIgnoreCase(strCol)) { isStatCol = true; if (mpStatValue.get(strCol) == null) bdStat = new BigDecimal("0"); else bdStat = new BigDecimal(mpStatValue.get(strCol)); if (strValue.length() == 0) strValue = "0"; // _log.showDebug("bdStat.add(new BigDecimal(strValue)) = " + bdStat.add(new // BigDecimal(strValue))); mpStatValue.put(strCol, bdStat.add(new BigDecimal(strValue)).toString()); } } } } } // 填写每页小计 if (isStatCol == true) { currRow++; row = sheet.getRow(currRow); if (row == null) row = sheet.createRow(currRow); cell = row.getCell(cntCol); if (cell == null) cell = row.createCell(cntCol); cell.setCellValue("小计"); for (int i = 0, colNum = lsStatCol.size(); i < colNum; i++) { mpField = lsStatCol.get(i); posis = getPosition(mpField.get("col_pos")); // if (row == null) row = sheet.createRow(posi + cnt); cell = row.getCell(posis[1]); if (cell == null) cell = row.createCell(posis[1]); strColCode = (mpField.get("col_code")).toLowerCase(); strValue = mpStatValue.get(strColCode); strStyle = mpField.get("format"); strValue = convertValue(strValue, strStyle); cell.setCellValue(strValue.trim()); } } return sheet; }
/** * 主键编码规则为:前缀+3位随机数字+流水号 前缀 -- 采用项目代号; 3位随机号 -- 为保证主键值唯一 流水号 -- 采用唯一的数字; * * <p>主键序号生成设计思想与CodeCreator编码序号相同。 * * @author TonyTan * @version 1.0, 2010-11-4 */ public class KeyCreator { private static KeyCreator _instance = new KeyCreator(); private static Log _log = Log.getInstance(); private static BaseDao _dao = BaseDao.getInstance(); // 每次取主键数量 private static final int POOL_SIZE = 10000000; // 缓存不同表的键对象 private static Map<String, KeyInfo> _keyList = FactoryUtil.newMap(); private KeyCreator() {} public static KeyCreator getInstance() { return _instance; } /** * 创建一数据表的主键值. * * @param tableName - 数据表名 * @return */ public synchronized String createKey(String tableName) { return getKeyPrefix() + getRandom() + createSerialNo(tableName); } /** * 创建新的树型记录ID * * @param parentID * @param level * @param tableName * @param pkField * @param levelCol * @param dsName * @return */ public synchronized String createTreeKey( String parentID, int level, String tableName, String pkField, String levelCol, String dsName) { if (parentID == null) parentID = ""; StringBuilder selsql = new StringBuilder(); StringBuilder wheresql = new StringBuilder(); selsql.append(" select max(" + pkField + ") as maxval, count(" + pkField + ") as cnt "); wheresql.append(" from " + tableName); if (parentID.length() == 0) { wheresql.append(" where " + pkField + " like '%' "); wheresql.append(" and " + levelCol + " = " + level); } else { wheresql.append(" where " + pkField + " like '" + parentID + "%' "); wheresql.append(" and " + levelCol + " = " + level); } selsql.append(wheresql); _log.showDebug("treeid selectsql = " + selsql.toString()); DaoParam param = _dao.createParam(selsql.toString()); param.setDsName(dsName); Map<String, String> keyMap = _dao.queryMap(param); String maxVal = keyMap.get("maxval"); if (maxVal.length() == 0) { if (parentID.length() == 0) { return "1001"; } else { // 本级别第一个节点 return parentID + "0001"; } } else { if (maxVal.equals("9999")) { _log.showWarn("treeid exceed 9999!"); return "9999"; } } maxVal = "0000" + (Long.parseLong(maxVal) + 1); String treeID = parentID + maxVal.substring(maxVal.length() - 4, maxVal.length()); return treeID; } /** * 取配置文件中的项目代号为主键前缀 * * @return */ private String getKeyPrefix() { String prefix = SystemConfig.getConfigByKey("ServerConfigs", "projectcode"); if (prefix.length() == 0) prefix = "dh"; return prefix; } /** * 取主键的序号 * * @return */ private String createSerialNo(String tableName) { KeyInfo keyInfo; tableName = tableName.toLowerCase(); if (_keyList.containsKey(tableName)) { keyInfo = _keyList.get(tableName); } else { // 如果缓存对象数量超过1000,则清除所有缓存对象 if (_keyList.size() > 1000) { _keyList.clear(); } keyInfo = new KeyInfo(POOL_SIZE, tableName); _keyList.put(tableName, keyInfo); } // 取新的序号 int serial = keyInfo.getNextKey(); return Integer.toString(serial); } /** * 为确保主键万无一失,每个主键前加一个3位随机数 * * @return */ private String getRandom() { int random = (int) (Math.random() * 1000); StringBuilder fix = new StringBuilder(Integer.toString(random)); int len = 3 - fix.length(); for (int i = 0; i < len; fix.insert(0, '0'), i++) ; return fix.toString(); } /** * 主键唯一序号生成类 * * @author TonyTan * @version 1.0, 2010-11-2 */ private class KeyInfo { private int keyMax; private int keyMin; private int nextKey; private int poolSize; private String keyName; public KeyInfo(int poolSize, String keyName) { this.poolSize = poolSize; this.keyName = keyName; retrieveFromDB(); } public int getNextKey() { if (nextKey > keyMax) { retrieveFromDB(); } // 每次取新号时,更新当前最大值;采用累加1的方式可以解决多线程多事务累加不丢失的问题。 String usql = "update sys_tableid set max_value = max_value + 1 where table_name = ?"; DaoParam uparam = _dao.createParam(usql); uparam.addStringValue(keyName); if (!_dao.update(uparam)) { _log.showWarn("get next code no update error!! tablename={0}!!", keyName); } return nextKey++; } private void retrieveFromDB() { // 从数据库中取上次分配的最大值 int dbmax = 0; String ssql = "select max_value from sys_tableid where table_name = ?"; DaoParam sparam = _dao.createParam(ssql); sparam.addStringValue(keyName); Map<String, String> mpMax = _dao.queryMap(sparam); if (!mpMax.isEmpty()) { dbmax = Integer.parseInt(mpMax.get("max_value")); } else { // 新建一条记录 String usql = "insert into sys_tableid(max_value, table_name) values(0, ?)"; DaoParam uparam = _dao.createParam(usql); uparam.addStringValue(keyName); if (!_dao.update(uparam)) { _log.showWarn("get next keyid no update error!! tablename={0}!!", keyName); } } keyMax = dbmax + poolSize; keyMin = dbmax + 1; nextKey = keyMin; } } }