diff --git a/src/main/java/com/nis/util/excel/ExcelCsv.java b/src/main/java/com/nis/util/excel/ExcelCsv.java new file mode 100644 index 000000000..b3350b737 --- /dev/null +++ b/src/main/java/com/nis/util/excel/ExcelCsv.java @@ -0,0 +1,424 @@ +package com.nis.util.excel; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; +import com.nis.util.DictUtils; +import com.nis.util.Reflections; +import com.nis.util.StringUtil; + +public class ExcelCsv { + + private static Logger log = LoggerFactory.getLogger(ExcelCsv.class); + + private static BufferedWriter cs; + + /**解决乱码问题 + * @see http://www.cnblogs.com/tangkai/p/3818084.html + */ + private final static byte bom[] = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }; + private final static String charset = "UTF-8"; + + /** + * 注解列表(Object[]{ ExcelField, Field/Method }) + */ + List annotationList = Lists.newArrayList(); + static Map> annotationMap=new HashMap<>(); + + /** + * //递归获取cls实体对象及父级对象的method + * @param list + * @param cls + */ + public static void getMethods(List list,Class cls) { + Method[] methods=cls.getDeclaredMethods(); + if(methods != null && methods.length > 0){ + List tempList=new ArrayList<>(); + for (Method method : methods) { + if(list.size()==0) { + tempList.add(method); + }else { + boolean has=false; + for(Method checkM:list) { + if(checkM.getName().equals(method.getName())) { + has=true; + break; + } + } + if(!has) { + tempList.add(method); + } + } + } + list.addAll(tempList); + } + if(cls.getSuperclass() != null){ + getMethods(list,cls.getSuperclass()); + } + } + + /** + * //递归获取cls实体对象及父级对象的属性 + * wx:修改,子类覆盖父类的同名方法 + * @param list + * @param cls + */ + public static void getFields(List list,Class cls) { + Field[] fields=cls.getDeclaredFields(); + if(fields != null && fields.length > 0){ + List tempList=new ArrayList<>(); + for (Field field : fields) { + if(list.size()==0) { + tempList.add(field); + }else { + boolean has=false; + for(Field checkF:list) { + if(checkF.getName().equals(field.getName())) { + has=true; + break; + } + } + if(!has) { + tempList.add(field); + } + } + } + list.addAll(tempList); + } + if(cls.getSuperclass() != null){ + getFields(list,cls.getSuperclass()); + } + } + + /** + * 构造函数 + * @param msgProp 国际化配置 + * @param title sheet名称 + * @param cls 实体对象,通过annotation.ExportField获取标题 + * @param type 导出类型(1:导出数据;2:导出模板) + * @param groups 导入分组 + * @return + */ + public static Map> ExcelCsvHeader(Properties msgProp,List titleList,Map noExportMap,Map> clsMap, int type, int... groups){ + Map> headerMap=new HashMap>(); + Map> commentMap=new HashMap>(); + for (String title : titleList) { + String noExportField=noExportMap.get(title); + List annotationList = Lists.newArrayList(); + List list=new ArrayList(); + // Get annotation field + //递归获取cls实体对象及父级对象的属性 + getFields(list, clsMap.get(title)); + if(!StringUtil.isEmpty(list)){ + for (Field f : list){ + ExcelField ef = f.getAnnotation(ExcelField.class); + if (ef != null && (ef.type()==0 || ef.type()==type)){ + if (groups!=null && groups.length>0){ + boolean inGroup = false; + for (int g : groups){ + if (inGroup){ + break; + } + for (int efg : ef.groups()){ + if (g == efg){ + inGroup = true; + if(!StringUtil.isEmpty(ef.title()) && !(noExportField.indexOf(","+ef.title()+",") > -1)){ + annotationList.add(new Object[]{ef, f}); + } + break; + } + } + } + }else{ + if(!StringUtil.isEmpty(ef.title()) && !(noExportField.indexOf(","+ef.title()+",") > -1)){ + annotationList.add(new Object[]{ef, f}); + } + } + } + } + } + List ms=new ArrayList(); + // Get annotation method + //递归获取cls实体对象及父级对象的属性 + getMethods(ms, clsMap.get(title)); + if(!StringUtil.isEmpty(ms)){ + for (Method m : ms){ + ExcelField ef = m.getAnnotation(ExcelField.class); + if (ef != null && (ef.type()==0 || ef.type()==type)){ + if (groups!=null && groups.length>0){ + boolean inGroup = false; + for (int g : groups){ + if (inGroup){ + break; + } + for (int efg : ef.groups()){ + if (g == efg){ + inGroup = true; + if(!StringUtil.isEmpty(ef.title()) && !(noExportField.indexOf(","+ef.title()+",") > -1)){ + annotationList.add(new Object[]{ef, m}); + } + break; + } + } + } + }else{ + if(!StringUtil.isEmpty(ef.title()) && !(noExportField.indexOf(","+ef.title()+",") > -1)){ + annotationList.add(new Object[]{ef, m}); + } + + } + } + } + } + // Field sorting + Collections.sort(annotationList, new Comparator() { + public int compare(Object[] o1, Object[] o2) { + return new Integer(((ExcelField)o1[0]).sort()).compareTo( + new Integer(((ExcelField)o2[0]).sort())); + }; + }); + // Initialize + List headerList = Lists.newArrayList(); + List commentList = Lists.newArrayList(); + for (Object[] os : annotationList){ + String titleStr = ((ExcelField)os[0]).title(); + String commentStr = ((ExcelField)os[0]).comment(); + + // 如果是导出,则去掉注释 + if (type==1){ + commentStr=""; + } + if(!StringUtil.isEmpty(titleStr)){ + //去掉不需要展示的header + if(!(noExportField.indexOf(","+titleStr+",") > -1)){ + //需要替换的header + boolean flag=true; + if(noExportField.contains("&")){ + String replaceField=noExportField.substring(noExportField.indexOf("&")+1); + String[] replaceStr=replaceField.split("-"); + for (int i = 0; i < replaceStr.length; i++) { + String [] fields=replaceStr[i].split(":"); + if(fields[0].equals(titleStr)){ + titleStr=msgProp.getProperty(fields[1]); + flag=false; + break; + } + } + } + if(flag){ + titleStr=msgProp.getProperty(titleStr)==null?titleStr:msgProp.getProperty(titleStr); + } + headerList.add(titleStr); + commentList.add(commentStr); + } + } + } + headerMap.put(title, headerList); + commentMap.put(title, commentList); + annotationMap.put(title, annotationList); + } + return headerMap; + } + + + + + /** + * 添加数据(通过annotation.ExportField添加数据) + * @param + * @return list 数据列表 + */ + public static Map> setDataList(Properties msgProp, Map dataMap, Map map){ + Map> dataList=new HashMap>(); + Set keyList=dataMap.keySet(); + for (String key : keyList) { + List list=dataMap.get(key); + List listT=new ArrayList(); + for (E e : list){ + int colunm = 0; + StringBuilder sb = new StringBuilder(); + for (Object[] os : annotationMap.get(key)){ + ExcelField ef = (ExcelField)os[0]; + Object val = null; + // Get entity value + try{ + if (StringUtils.isNotBlank(ef.value())){ + val = Reflections.invokeGetter(e, ef.value()); + }else{ + if (os[1] instanceof Field){ + val = Reflections.invokeGetter(e, ((Field)os[1]).getName()); + }else if (os[1] instanceof Method){ + val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {}); + } + } + // If is dict, get dict label + if (StringUtils.isNotBlank(ef.dictType())){ + String valStr=val==null?"":val.toString(); + //字典数据已做国际化处理 + String dict=DictUtils.getDictLabel(ef.dictType(), valStr, valStr); + //如果找不到字典国际化值,把字典本身作为默认值放进去,不然导出就是空了 + val = msgProp.getProperty(dict,dict); + + } + if(ef.title().equals("is_hex") && !StringUtil.isEmpty(val)){ + Integer isHex=Integer.parseInt(val.toString()); + if(isHex.equals(0) || isHex.equals(2)){ + val = msgProp.getProperty("not_hex","not_hex"); + }else if(isHex.equals(1)){ + val = msgProp.getProperty("hex","hex"); + }else{ + val =""; + } + } + if(ef.title().equals("is_case_insenstive") && !StringUtil.isEmpty(val)){ + Integer isCaseSenstive=Integer.parseInt(val.toString()); + if(isCaseSenstive.equals(0) || isCaseSenstive.equals(1)){ + val = msgProp.getProperty("case_insenstive","case_insenstive"); + }else if(isCaseSenstive.equals(1)){ + val = msgProp.getProperty("case_senstive","case_senstive"); + }else{ + val =""; + } + } + }catch(Exception ex) { + log.error("Get entity value failed",ex); + val = ""; + } + sb.append(val + ", "); + } + listT.add(String.valueOf(sb)); + } + dataList.put(key, listT); + } + return dataList; + } + + public static void writeCSVFile(HttpServletResponse response,List titleList,Map> headMap, Map> dataMap,String fileName) { + try { + // 写入临时文件 + File tempFile = File.createTempFile("vehicle", ".csv"); + cs = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "utf-8"), 1024); + cs.write(new String(bom, charset)); + //获取头部数据 + if(titleList.size()>0){ + List heads=headMap.get(titleList.get(0)); + // 写入文件头部 + writeHead(heads, cs); + //获取文件内容 + List datas=dataMap.get(titleList.get(0)); + // 写入文件内容 + for (String row : datas) { + writeRow(row, cs); + } + } + cs.flush(); + OutputStream out = response.getOutputStream(); + byte[] b = new byte[10240]; + File fileLoad = new File(tempFile.getCanonicalPath()); + response.reset(); + response.setContentType("application/octet-stream; charset=utf-8"); + response.setHeader("Content-Disposition", "attachment; filename="+fileName); + long fileLength = fileLoad.length(); + String length1 = String.valueOf(fileLength); + response.setHeader("Content_Length", length1); + FileInputStream in = new FileInputStream(fileLoad); + int n; + while ((n = in.read(b)) != -1) { + out.write(b, 0, n); // 每次写入out1024字节 + } + in.close(); + out.close(); + deleteFile(tempFile); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static boolean deleteFile( File file) { + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + private static void writeHead(List titles, BufferedWriter csvWriter) throws IOException { + // 写入文件头部 + for (String title : titles) { + StringBuffer sb = new StringBuffer(); + String rowStr = sb.append("\"").append(title).append("\",").toString(); + csvWriter.write(rowStr); + } + csvWriter.newLine(); + } + + private static void writeRow(String data, BufferedWriter csvWriter) throws Exception { + // 写入文件内容 + String [] datas=data.split(","); + for (String tag : datas) { + StringBuffer sb = new StringBuffer(); + if(StringUtils.isNotBlank(tag)){ + // 替换值中双引号 + if(tag.contains("\"")){ + tag = tag.replace("\"", ""); + } + // \t解决数字0开头字符串,0显示不出来的问题,比如邮编 + if(tag.startsWith("0") && !tag.contains(".")){ + tag = tag + "\t"; + } + if(isDate(tag)){ + tag=tag + "\t"; + } + + } + String rowStr = sb.append("\"").append(tag==null?"":tag).append("\",").toString(); + csvWriter.write(rowStr); + } + csvWriter.newLine(); + } + /** + * 功能:判断字符串是否为日期格式 + * + * @param str + * @return + */ + public static boolean isDate(String strDate) { + Pattern pattern = Pattern + .compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"); + Matcher m = pattern.matcher(strDate); + if (m.matches()) { + return true; + } else { + return false; + } + } + + +} \ No newline at end of file diff --git a/src/main/java/com/nis/web/controller/log/ntc/NtcCollectRadiusLogController.java b/src/main/java/com/nis/web/controller/log/ntc/NtcCollectRadiusLogController.java index cfe4e5a9a..14cee9753 100644 --- a/src/main/java/com/nis/web/controller/log/ntc/NtcCollectRadiusLogController.java +++ b/src/main/java/com/nis/web/controller/log/ntc/NtcCollectRadiusLogController.java @@ -80,7 +80,7 @@ public class NtcCollectRadiusLogController extends BaseController { //radius配置导出 @RequestMapping(value = "exportRadius") - public void exportRadius(@ModelAttribute("log") NtcCollectRadiusLog log, Model model,String hColumns, HttpServletRequest request, HttpServletResponse response,RedirectAttributes redirectAttributes){ + public void exportRadius(@ModelAttribute("log") NtcCollectRadiusLog log, Model model,String hColumns,String type, HttpServletRequest request, HttpServletResponse response,RedirectAttributes redirectAttributes){ try { //export data info List titleList=new ArrayList(); @@ -126,12 +126,15 @@ public class NtcCollectRadiusLogController extends BaseController { noExportMap.put("radius_log",cfgIndexInfoNoExport); dataMap.put("radius_log",list); /*}*/ - this._export(model, request, response, redirectAttributes,"radius_log",titleList,classMap,dataMap,noExportMap); + if("csv".equals(type)){ + this._exportCsv(model, request, response, redirectAttributes,"radius_log",titleList,classMap,dataMap,noExportMap); + }else{ + this._export(model, request, response, redirectAttributes,"radius_log",titleList,classMap,dataMap,noExportMap); + } } catch (Exception e) { logger.error("radius export failed",e); addMessage(redirectAttributes,"error","export_failed"); } } - } diff --git a/src/main/webapp/WEB-INF/views/log/ntc/radiusLogList.jsp b/src/main/webapp/WEB-INF/views/log/ntc/radiusLogList.jsp index b394b2a04..d3364395f 100644 --- a/src/main/webapp/WEB-INF/views/log/ntc/radiusLogList.jsp +++ b/src/main/webapp/WEB-INF/views/log/ntc/radiusLogList.jsp @@ -105,7 +105,7 @@