From f16937b841aea86a95840cbd845e6e11b6a197b1 Mon Sep 17 00:00:00 2001 From: cnlimiter Date: Tue, 20 Feb 2024 15:30:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(fabric):=20=E7=BE=A4=E6=9C=8D=E7=BB=91?= =?UTF-8?q?=E5=AE=9Aapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/evole/mods/mcbot/cmds/CmdApi.java | 4 +- .../cn/evole/mods/mcbot/data/UserBind.java | 23 ++ .../main/java/com/xykj/easycsv/Converter.java | 371 ++++++++++++++++++ .../main/java/com/xykj/easycsv/CsvWriter.java | 181 +++++++++ .../main/java/com/xykj/easycsv/EasyCsv.java | 336 ++++++++++++++++ .../com/xykj/easycsv/entity/CsvProperty.java | 21 + .../com/xykj/easycsv/entity/IgnoreField.java | 12 + .../java/com/xykj/easycsv/entity/Rule.java | 55 +++ .../xykj/easycsv/listener/CsvListener.java | 31 ++ .../easycsv/listener/CsvToMapListener.java | 10 + 10 files changed, 1042 insertions(+), 2 deletions(-) create mode 100644 fabric/src/main/java/cn/evole/mods/mcbot/data/UserBind.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/Converter.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/CsvWriter.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/EasyCsv.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/entity/CsvProperty.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/entity/IgnoreField.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/entity/Rule.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/listener/CsvListener.java create mode 100644 fabric/src/main/java/com/xykj/easycsv/listener/CsvToMapListener.java diff --git a/fabric/src/main/java/cn/evole/mods/mcbot/cmds/CmdApi.java b/fabric/src/main/java/cn/evole/mods/mcbot/cmds/CmdApi.java index b0a3862..0666c2a 100644 --- a/fabric/src/main/java/cn/evole/mods/mcbot/cmds/CmdApi.java +++ b/fabric/src/main/java/cn/evole/mods/mcbot/cmds/CmdApi.java @@ -17,9 +17,9 @@ public class CmdApi { private static StringBuilder CmdMain(String cmd, boolean isOp) { StringBuilder result = new StringBuilder(); //#if MC >= 11900 - McBot.SERVER.getCommands().performPrefixedCommand(isOp ? BotCmdRun.OP : BotCmdRun.CUSTOM, cmd);//优雅 + //$$ McBot.SERVER.getCommands().performPrefixedCommand(isOp ? BotCmdRun.OP : BotCmdRun.CUSTOM, cmd);//优雅 //#else - //$$ McBot.SERVER.getCommands().performCommand(isOp ? BotCmdRun.OP : BotCmdRun.CUSTOM, cmd); + McBot.SERVER.getCommands().performCommand(isOp ? BotCmdRun.OP : BotCmdRun.CUSTOM, cmd); //#endif for (String s : (isOp ? BotCmdRun.OP.outPut : BotCmdRun.CUSTOM.outPut)) { result.append(s.replaceAll("§\\S", "")).append("\n"); diff --git a/fabric/src/main/java/cn/evole/mods/mcbot/data/UserBind.java b/fabric/src/main/java/cn/evole/mods/mcbot/data/UserBind.java new file mode 100644 index 0000000..bf3fe59 --- /dev/null +++ b/fabric/src/main/java/cn/evole/mods/mcbot/data/UserBind.java @@ -0,0 +1,23 @@ +package cn.evole.mods.mcbot.data; + +import com.xykj.easycsv.entity.CsvProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @Project: McBot-fabric + * @Author: cnlimiter + * @CreateTime: 2024/2/20 14:56 + * @Description: + */ + +@Getter +@Setter +public class UserBind { + @CsvProperty("学号") + private int no; + @CsvProperty("姓名") + private String name; + @CsvProperty("年龄") + private Integer age; +} diff --git a/fabric/src/main/java/com/xykj/easycsv/Converter.java b/fabric/src/main/java/com/xykj/easycsv/Converter.java new file mode 100644 index 0000000..585c9f9 --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/Converter.java @@ -0,0 +1,371 @@ +package com.xykj.easycsv; + +import com.xykj.easycsv.entity.CsvProperty; +import com.xykj.easycsv.entity.Rule; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.util.*; + +/** + * 转化器 + */ +public class Converter { + + /** + * 分割工具 + * 分割工具 + */ + private Rule rule; + + public Converter(Rule rule) { + this.rule = rule; + } + + public Converter() { + this.rule = null; + } + + + + /** + * 标题名-标题index + */ + private Map titleIndexMap =new LinkedHashMap<>(); + + /** + * 标题名-实体类属性名 + */ + Map titleFieldMap=null; + + /** + * 属性-坐标实体类 + */ + Map fieldIndexMap=null; + + public Map getFieldIndexMap() { + return fieldIndexMap; + } + + public void setFieldIndexMap(Map fieldIndexMap) { + this.fieldIndexMap = fieldIndexMap; + } + + public Map getTitleIndexMap() { + return titleIndexMap; + } + + public Map getTitleFieldMap() { + return titleFieldMap; + } + + public void setTitleIndexMap(String titleColumn){ + String[] strList = getStrList(titleColumn); + for (int i = 0; i < strList.length; i++) { + String title = strList[i]; + if (i==0&&title!=null){ + char c = title.charAt(0); + if (c=='\uFEFF'){ + title=title.substring(1); + } + } + titleIndexMap.put(title,i); + } + } + + /** + * 获取一个标题-参数名map + * @param a + * @param + * @return + */ + public Map getTitleFieldMap(Class a){ + + if (this.titleFieldMap!=null){ + return titleFieldMap; + } + Map fieldIndexMap=new LinkedHashMap<>(); + Map exprMap=new HashMap<>(); + for (Field field : a.getDeclaredFields()) { + CsvProperty annotation = field.getAnnotation(CsvProperty.class); + if (annotation==null){ + continue; + } + String name = field.getName(); + int index = annotation.index(); + if (index!=-1){ + fieldIndexMap.put(name,index); + } + String titleName = annotation.value(); + if (!"".equals(titleName)){ + exprMap.put(name,titleName); + } + } + this.fieldIndexMap=fieldIndexMap; + this.titleFieldMap=exprMap; + return exprMap; + } + + /** + * 获取一个实例 + * @param str + * @param classA + * @param + * @return + */ + public T getT(String str,Class classA) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + String[] cells = getStrList(str); + final Map titleFieldMap = getTitleFieldMap(classA); + return getT(cells,classA,titleFieldMap); + } + + public Map getMap(String str){ + String[] cells = getStrList(str); + Map result=new LinkedHashMap<>(); + for (int i = 0; i < cells.length; i++) { + result.put(i,cells[i]); + } + return result; + } + + /** + * 获取一条实例 + * @param cells 一行数据 + * @param a 返回对象的类型 + * @param titleFieldMap 标题-参数map 参数为对象的参数 + * @param + * @return + */ + private T getT(String[] cells, Class a,Map titleFieldMap) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + T result = a.newInstance(); + Field[] fields = result.getClass().getDeclaredFields(); + for (Field field : fields) { + String fieldName = field.getName(); + //先通过索引注解查询 + Integer index = this.fieldIndexMap.get(fieldName); + if (index != null) { + if(index>cells.length-1){ + break; + } + String cellValue = cells[index]; + invoke(cellValue, field, result); + } + String title = titleFieldMap.get(fieldName); + if (title != null) { + String cellValue = getCellByTitle(title, cells); + invoke(cellValue, field, result); + } + } + return result; + } + + /** + * 设置值 + * @param cellValue + * @param method + * @param result + * @param + * @throws InvocationTargetException + * @throws IllegalAccessException + */ + public void invoke(String cellValue,Method method,T result) throws InvocationTargetException, IllegalAccessException { + if (cellValue!=null){ + Class parameterType = method.getParameterTypes()[0]; + Object value = parseValue(parameterType, cellValue); + if (value!=null){ + method.invoke(result,value); + } + } + } + + public void invoke(String cellValue,Field field,T result) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + if (cellValue!=null){ + Class parameterType = field.getType(); + Method method = getSetMethodByFieldName(field, result); + Object value = parseValue(parameterType, cellValue); + if (value!=null){ + method.invoke(result,value); + } + } + } + + public Method getSetMethodByFieldName(Field field, T result) throws NoSuchMethodException { + String fieldName=field.getName(); + Character firstChar = fieldName.charAt(0); + fieldName = firstChar.toString().toUpperCase(Locale.ROOT) + fieldName.substring(1); + String methodName="set"+fieldName; + return result.getClass().getMethod(methodName,field.getType()); + } + + /** + * + * @param title + * @param cells + * @return + */ + public String getCellByTitle(String title,String[] cells){ + Integer index = titleIndexMap.get(title); + if (index!=null&&index!=-1){ + return cells[index]; + } + return null; + } + + private String split=null; + + /** + * 将一整行字符串分割成一个个单元格 + * @param str + * @return + */ + private String[] getStrList(String str){ + if (rule!=null){ + getStrListByRule(str); + } + return getDefaultStrList(str); + } + + public String[] getStrListByRule(String str){ + if (split==null){ + String startWith = ""; + if (rule.getStartWith()!=null){ + startWith=rule.getStartWith(); + } + String endWith = ""; + if (rule.getEndWith()!=null){ + endWith=rule.getEndWith(); + } + String split = rule.getSplit(); + this.split=endWith + split + startWith; + } + String[] split1 = split(str,this.split); + String first = split1[0]; + String last = split1[split1.length-1]; + split1[0]=first.replaceFirst(rule.getStartWith(),""); + split1[split1.length-1]=last.substring(0,last.lastIndexOf(rule.getEndWith())); + return split1; + } + + public String[] getDefaultStrList(String str){ +// String[] split = str.split(","); + String[] split = split(str,","); + for (int i = 0; i < split.length; i++) { + String s=split[i]; + if ((s.indexOf("\"")==0)&&(s.lastIndexOf("\"")==(s.length()-1))){ + s=s.substring(1,s.length()-2); + } + split[i]=s; + } + return split; + } + + private static String[] split(String str,String regex){ + List cellList=new ArrayList<>(); + int fromIndex=0; + int cellStartIndex=0; + while (cellStartIndex<=str.length()-1){ + fromIndex = str.indexOf(regex, fromIndex); + if (fromIndex==-1){ + fromIndex=str.length(); + } + int cellEndIndex =fromIndex; + if (cellStartIndex==fromIndex){ + cellList.add(""); + }else { + cellList.add(str.substring(cellStartIndex,cellEndIndex)); + } + fromIndex=fromIndex+regex.length(); + cellStartIndex=fromIndex; + } + if (str.lastIndexOf(regex)+regex.length()==str.length()){ + cellList.add(""); + } + String [] result=new String[cellList.size()]; + for (int i = 0; i < cellList.size(); i++) { + result[i]=cellList.get(i); + } + return result; + } + + /** + * 获取参数名称 + * @param method + * @return + */ + public String getFieldName(Method method){ + String name = method.getParameters()[0].getName(); + return name; + } + + + /** + * 将表格的值转换成对象属性的类型 + * @param parameterType + * @param cellValue + * @return + */ + public Object parseValue(Class parameterType,String cellValue){ +// String parameterTypeStr = parameterType.toString(); + Object result=null; + try { + if (parameterType.equals(BigDecimal.class)){ + result=new BigDecimal(cellValue); + }else if (cellValue==null){ + System.out.println("一条空值"); + }else if (parameterType.equals(String.class)){ + result=cellValue; + }else if (parameterType.equals(Integer.class)|| "int".equals(parameterType.getName())){ + result= parseInt(cellValue); + }else if (parameterType.equals(Float.class)|| "float".equals(parameterType.getName())){ + result=parseFloat(cellValue); + }else if (parameterType.equals(Double.class)|| "double".equals(parameterType.getName())){ + result=parseDouble(cellValue); + }else if (parameterType.equals(Long.class)|| "long".equals(parameterType.getName())){ + result=parseLong(cellValue); + }else if (parameterType.equals(Short.class)|| "short".equals(parameterType.getName())){ + result=parseShort(cellValue); + }else if (parameterType.equals(Boolean.class)|| "boolean".equals(parameterType.getName())){ + result=Boolean.parseBoolean(cellValue); + }else if (parameterType.equals(Character.class)||"char".equals(parameterType.getName())){ + result=cellValue.charAt(0); + } + }catch (Exception e){ + System.out.println("类型转换异常-无法将值‘"+cellValue+"’转换成‘"+parameterType+"’类型"); + e.printStackTrace(); + } + return result; + } + + private int parseInt(String value){ + if (value==null||"".equals(value)){ + return 0; + } + return new BigDecimal(value).intValue(); + } + private float parseFloat(String value){ + if (value==null||"".equals(value)){ + return 0; + } + return new BigDecimal(value).floatValue(); + } + private long parseLong(String value){ + if (value==null||"".equals(value)){ + return 0; + } + return new BigDecimal(value).longValue(); + } + private double parseDouble(String value){ + if (value==null||"".equals(value)){ + return 0; + } + return new BigDecimal(value).doubleValue(); + } + private short parseShort(String value){ + if (value==null||"".equals(value)){ + return 0; + } + return new BigDecimal(value).shortValue(); + } +} diff --git a/fabric/src/main/java/com/xykj/easycsv/CsvWriter.java b/fabric/src/main/java/com/xykj/easycsv/CsvWriter.java new file mode 100644 index 0000000..86e277a --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/CsvWriter.java @@ -0,0 +1,181 @@ +package com.xykj.easycsv; + +import com.xykj.easycsv.Converter; +import com.xykj.easycsv.entity.CsvProperty; +import com.xykj.easycsv.entity.IgnoreField; +import com.xykj.easycsv.entity.Rule; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 写出工具 + */ +public class CsvWriter { + + private Rule rule; + + public CsvWriter(Rule rule) { + if (rule==null){ + this.rule=new Rule(null,null,","); + }else { + this.rule=rule; + } + } + + /** + * 属性-标题Map + */ + Map fieldTitleMap; + + public void doWrite(String outputPath, List dataList){ + + File outputFile=new File(outputPath); + Writer writer=null; + try { + outputFile.createNewFile(); + writer=new FileWriter(outputFile,true); + for (int i = 0; i < dataList.size(); i++) { + T t = dataList.get(i); + String oneRow; + if (i==0){ + fieldTitleMap = getFieldTitleMap(t.getClass()); + oneRow = getTitleRowStr(); + writer.write(oneRow); + } + oneRow = getOneRowStr(t); + writer.write(oneRow); + } + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 获取一行的字符串 + * @param t + * @param + * @return + */ + private String getOneRowStr(T t){ + List oneRow = getOneRow(t); + return listToStr(oneRow); + } + + + private List getOneRow(T t){ + List result=new ArrayList<>(); + Field[] fields = t.getClass().getDeclaredFields(); + for (Field field : fields) { + String fieldName = field.getName(); + if (fieldTitleMap.containsKey(fieldName)){ + try { + + field.setAccessible(true); + + Object value =field.get(t); + if (value==null){ + result.add(""); + }else { + result.add(value.toString()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return result; + } + + /** + * 获取一行字符串 + * @return + */ + private String listToStr(List list){ + StringBuilder result=new StringBuilder(""); + for (int i = 0; i < list.size(); i++) { + String cell = list.get(i); + if (i==0){ + if (rule.getStartWith()!=null){ + result.append(rule.getStartWith()); + } + result.append(cell); + if (rule.getEndWith()!=null){ + result.append(rule.getEndWith()); + } + }else{ + result.append(rule.getSplit()); + if (rule.getStartWith()!=null){ + result.append(rule.getStartWith()); + } + result.append(cell); + if (rule.getEndWith()!=null){ + result.append(rule.getEndWith()); + } + } + } + result.append("\n"); + return result.toString(); + } + +// public Method getGetMethodByFieldName(Field field, T result) throws NoSuchMethodException { +// String fieldName=field.getName(); +// Character firstChar = fieldName.charAt(0); +// fieldName = firstChar.toString().toUpperCase(Locale.ROOT) + fieldName.substring(1); +// String methodName="get"+fieldName; +// Class type = field.getType(); +// return result.getClass().getmethod() +// } + + /** + * 获取标题行字符串 + * @return + */ + private String getTitleRowStr(){ + StringBuilder result=new StringBuilder(""); + boolean isFirst=true; + List titles = this.fieldTitleMap.keySet().stream().map(e -> this.fieldTitleMap.get(e)).collect(Collectors.toList()); + return listToStr(titles); + } + + private Map getFieldTitleMap(Class tClass){ + fieldTitleMap=new LinkedHashMap<>(); + for (Field field : tClass.getDeclaredFields()) { + IgnoreField ignoreField = field.getAnnotation(IgnoreField.class); + //如果有忽略注解,此字段将不处理 + if (ignoreField!=null){ + continue; + } + String fieldName = field.getName(); + CsvProperty annotation = field.getAnnotation(CsvProperty.class); + if (annotation!=null){ + String titleName = annotation.value(); + if (!"".equals(titleName)){ + fieldTitleMap.put(fieldName,titleName); + }else { + fieldTitleMap.put(fieldName,fieldName); + } + }else { + //如果此注解为空,则用类的属性名直接当标题 + fieldTitleMap.put(fieldName,fieldName); + } + + } + return fieldTitleMap; + } + + +} diff --git a/fabric/src/main/java/com/xykj/easycsv/EasyCsv.java b/fabric/src/main/java/com/xykj/easycsv/EasyCsv.java new file mode 100644 index 0000000..e59412e --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/EasyCsv.java @@ -0,0 +1,336 @@ +package com.xykj.easycsv; + +import com.xykj.easycsv.entity.Rule; +import com.xykj.easycsv.listener.CsvListener; +import com.xykj.easycsv.listener.CsvToMapListener; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class EasyCsv { + + public String getCharsetName() { + if (charsetName!=null&& !charsetName.isEmpty()){ + return charsetName; + }else { + return "GBK"; + } + } + + public void setCharsetName(String charsetName) { + this.charsetName = charsetName; + } + + /** + * 编码集合 + */ + private String charsetName; + + private Rule rule; + + public Rule getRule() { + return rule; + } + + public void setRule(Rule rule) { + this.rule = rule; + } + + public EasyCsv(String charsetName) { + this.charsetName = charsetName; + } + + public EasyCsv(String charsetName, Rule rule) { + this.charsetName = charsetName; + this.rule = rule; + } + + public EasyCsv() { + } + + + public EasyCsv(Rule rule) { + this.rule = rule; + } + + + /** + * 生成CSV文件 + * @param filePath + * @param dataList + * @param + */ + public void write(String filePath,List dataList){ + new CsvWriter(this.rule).doWrite(filePath,dataList); + } + + + /** + * 获取所有数据 + * @param fileName 文件路径 + * @param classA 实体类class 类型 + * @param + * @return + */ + public List readAll(String fileName, Class classA){ + try { + return read(new FileInputStream(fileName), classA,null); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 流方式读 + * @param inputStream + * @param classA + * @param + * @return + */ + public List readAll(InputStream inputStream, Class classA) { + return read(inputStream, classA,null); + } + + + /** + * 以监听器的模式读取csv文件 + * @param fileName + * @param classA + * @param csvListener + * @param + */ + public void doRead(String fileName,Class classA, CsvListener csvListener) { + try { + read(new FileInputStream(fileName),classA,csvListener); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * 流方式读 + * @param inputStream + * @param classA + * @param csvListener + * @param + */ + public void doRead(InputStream inputStream,Class classA, CsvListener csvListener) { + read(inputStream,classA,csvListener); + } + + + /** + * 以监听器的方式读取csv文件转为Map对象 + * @param fileName + * @param csvToMapListener + */ + public void doReadCsvByMap(String fileName, CsvToMapListener csvToMapListener){ + readToMap(fileName, csvToMapListener); + } + + /** + * 内部读取将csv读取为Map结构 + * @param fileName + * @param csvListener + * @return + */ + private List> readToMap(String fileName, CsvToMapListener csvListener) { + BufferedReader reader = null; + List> result = new ArrayList<>(); + InputStream resourceAsStream=null; + try { + resourceAsStream = new FileInputStream(fileName); + reader = new BufferedReader(new InputStreamReader(resourceAsStream,"GBK")); + String oneColumnStr; + int i=0; + Converter converter=new Converter(this.rule); + while ((oneColumnStr = reader.readLine()) != null) { + if (i==0){ + converter.setTitleIndexMap(oneColumnStr); + if (csvListener!=null){ + csvListener.invokeHead(converter.getTitleIndexMap(),oneColumnStr); + } + }else { + if (csvListener!=null){ + csvListener.invoke(converter.getMap(oneColumnStr),oneColumnStr); + }else { + result.add(converter.getMap(oneColumnStr)); + } + } + i++; + } + if (csvListener!=null){ + csvListener.readOver(); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (reader != null) { + try { + resourceAsStream.close(); + reader.close(); + } catch (IOException e1) { } + } + } + return result; + } + + + + + /** + * 读取csv的内部方法 + * @param inputStream + * @param classA + * @param csvListener + * @param + * @return + */ + private List read(InputStream inputStream,Class classA, CsvListener csvListener) { + BufferedReader reader = null; + List result = new ArrayList<>(); + try { + reader = new BufferedReader(new InputStreamReader(inputStream,getCharsetName())); + String oneColumnStr; + int i=0; + Converter converter=new Converter(this.rule); + while ((oneColumnStr = reader.readLine()) != null) { + //如果开发人员没有指定编码格式,程序会自己检验字符格式并进行校正 + if (charsetName==null){ + String encoding = getEncoding(new ByteArrayInputStream(oneColumnStr.getBytes())); + oneColumnStr=new String(oneColumnStr.getBytes(encoding), StandardCharsets.UTF_8); + } + if (i==0){ + converter.setTitleIndexMap(oneColumnStr); + if (csvListener!=null){ + csvListener.invokeHead(converter.getTitleIndexMap(),oneColumnStr); + } + }else { + try { + if (csvListener!=null){ + csvListener.invoke(converter.getT(oneColumnStr, classA),oneColumnStr); + }else { + result.add(converter.getT(oneColumnStr, classA)); + } + }catch (Exception e){ + e.printStackTrace(); + if (csvListener!=null){ + csvListener.invoke(classA.newInstance(),oneColumnStr); + csvListener.onError(e,oneColumnStr); + }else { + result.add(classA.newInstance()); + } + } + } + i++; + } + if (csvListener!=null){ + csvListener.readOver(); + } + reader.close(); + } catch (IOException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e1) { + } + } + } + return result; + } + + + /** + * 获取内容编码 + * @return + */ + private static String getEncoding(ByteArrayInputStream is) { + is.mark(0); + String charset = "GBK"; + byte[] first3Bytes = new byte[3]; + try { + + boolean checked = false; + + int read = is.read(first3Bytes, 0, 3); + + if (read == -1) { + return charset; + } + if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) { + charset = "UTF-16LE"; + checked = true; + } else if (first3Bytes[0] == (byte) 0xFE + && first3Bytes[1] == (byte) 0xFF) { + charset = "UTF-16BE"; + checked = true; + } else if (first3Bytes[0] == (byte) 0xEF + && first3Bytes[1] == (byte) 0xBB + && first3Bytes[2] == (byte) 0xBF) { + charset = "UTF-8"; + checked = true; + }else if (first3Bytes[0] == (byte) 0xA + && first3Bytes[1] == (byte) 0x5B + && first3Bytes[2] == (byte) 0x30) { + charset = "UTF-8"; + checked = true; + }else if (first3Bytes[0] == (byte) 0xD + && first3Bytes[1] == (byte) 0xA + && first3Bytes[2] == (byte) 0x5B) { + charset = "GBK"; + checked = true; + }else if (first3Bytes[0] == (byte) 0x5B + && first3Bytes[1] == (byte) 0x54 + && first3Bytes[2] == (byte) 0x49) { + charset = "windows-1251"; + checked = true; + } + is.reset(); + is.mark(0); + if (!checked) { + int loc = 0; + while ((read = is.read()) != -1) { + loc++; + if (read >= 0xF0) { + break; + } + if (0x80 <= read && read <= 0xBF) { + break; + } + if (0xC0 <= read && read <= 0xDF) { + read = is.read(); + if (0x80 <= read && read <= 0xBF) { + continue; + } else { + break; + } + } else if (0xE0 <= read && read <= 0xEF) { + read = is.read(); + if (0x80 <= read && read <= 0xBF) { + read = is.read(); + if (0x80 <= read && read <= 0xBF) { + charset = "UTF-8"; + break; + } else { + break; + } + } else { + break; + } + } + } + } + is.reset(); + } catch (Exception e) { + e.printStackTrace(); + } + return charset; + } +} diff --git a/fabric/src/main/java/com/xykj/easycsv/entity/CsvProperty.java b/fabric/src/main/java/com/xykj/easycsv/entity/CsvProperty.java new file mode 100644 index 0000000..ef31ea7 --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/entity/CsvProperty.java @@ -0,0 +1,21 @@ +package com.xykj.easycsv.entity; + +import java.lang.annotation.*; + +/** + * + * excelparse注解 + * @author wangyiqian + */ +@Documented +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface CsvProperty { + /** + * Excel列的的标题 + * @return + */ + String value() default ""; + + int index() default -1; +} diff --git a/fabric/src/main/java/com/xykj/easycsv/entity/IgnoreField.java b/fabric/src/main/java/com/xykj/easycsv/entity/IgnoreField.java new file mode 100644 index 0000000..42aeb78 --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/entity/IgnoreField.java @@ -0,0 +1,12 @@ +package com.xykj.easycsv.entity; + +import java.lang.annotation.*; + +/** + * 在属性上添加此注解,输出csv文件时改字段将不会写入 + */ +@Documented +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface IgnoreField { +} diff --git a/fabric/src/main/java/com/xykj/easycsv/entity/Rule.java b/fabric/src/main/java/com/xykj/easycsv/entity/Rule.java new file mode 100644 index 0000000..6a81d3f --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/entity/Rule.java @@ -0,0 +1,55 @@ +package com.xykj.easycsv.entity; + +/** + * csv分割规则 + */ +public class Rule { + /** + * 开始符号 + */ + private String startWith=""; + + /** + * 结束符号 + */ + private String endWith=""; + + /** + * 分隔符号 + */ + private String split; + + + public Rule(String startWith, String endWith, String split) { + this.startWith = startWith; + this.endWith = endWith; + if (split==null||"".equals(split)){ + System.out.println("分割符不能为空"); + } + this.split = split; + } + + public String getStartWith() { + return startWith; + } + + public void setStartWith(String startWith) { + this.startWith = startWith; + } + + public String getEndWith() { + return endWith; + } + + public void setEndWith(String endWith) { + this.endWith = endWith; + } + + public String getSplit() { + return split; + } + + public void setSplit(String split) { + this.split = split; + } +} diff --git a/fabric/src/main/java/com/xykj/easycsv/listener/CsvListener.java b/fabric/src/main/java/com/xykj/easycsv/listener/CsvListener.java new file mode 100644 index 0000000..3c4ac12 --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/listener/CsvListener.java @@ -0,0 +1,31 @@ +package com.xykj.easycsv.listener; + +import java.util.Map; + +public interface CsvListener { + /** + * 初始化一行数据 + * @param data 实例化后的对象 + * @param sourceColumn 源数据行字符串 + */ + void invoke(T data,String sourceColumn); + + /** + * 初始化标题 + * @param titleIndexMap + * @param sourceColumn + */ + void invokeHead(Map titleIndexMap,String sourceColumn); + + + /** + * 当出现错误行时 + * @param sourceColumn + */ + void onError(Exception e,String sourceColumn); + + /** + * 读数据完毕 + */ + void readOver(); +} diff --git a/fabric/src/main/java/com/xykj/easycsv/listener/CsvToMapListener.java b/fabric/src/main/java/com/xykj/easycsv/listener/CsvToMapListener.java new file mode 100644 index 0000000..cd4da71 --- /dev/null +++ b/fabric/src/main/java/com/xykj/easycsv/listener/CsvToMapListener.java @@ -0,0 +1,10 @@ +package com.xykj.easycsv.listener; + +import java.util.Map; + +/** + * 将一行数据读取为 index-value map结构, + * @author wangyiqian + */ +public abstract class CsvToMapListener implements CsvListener>{ +}