package com.hy.utils;

    import com.hy.config.ApplicationConfig;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.ss.formula.functions.T;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;

    import javax.annotation.PreDestroy;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;

    /*
    生成csv文件


    */
    @Component
    public class MyCsvUtil {
    private static final Logger log = LoggerFactory.getLogger(MyCsvUtil.class);
    private static String csv_rootpath = ApplicationConfig.mylogRootPath;// 使用日志保存路径
    private static String csv_rootname = “csv”;
    private final static ExecutorService pool = Executors.newSingleThreadExecutor();
    @PreDestroy
    public void destroy(){
    System.out.print(“关闭MyCsvUtil线程池”);
    log.info(“关闭MyCsvUtil线程池”);
    shutdownPool();
    }
    private void shutdownPool(){
    //1、停止线程池接收新任务
    //2、等待一定时间,让现存的任务执行结束
    //3、取消当前运行的任务
    //4、如果当前线程也被中断的话,那么就再次关闭线程池,同时恢复中断状态

    1. try{<br /> pool.shutdown();<br /> if(!pool.awaitTermination(60,TimeUnit.SECONDS)){<br /> pool.shutdownNow();<br /> if(!pool.awaitTermination(60,TimeUnit.SECONDS)){<br /> System.out.println("ErrorCsvUtil Pool did not terminate");<br /> }<br /> }<br /> }catch(InterruptedException ie){<br /> pool.shutdownNow();<br /> Thread.currentThread().interrupt();<br /> }
    2. }
    3. /*<br /> * yyyy-MM: 每个月更新一个log日志 yyyy-ww: 每个星期更新一个log日志 yyyy-MM-dd: 每天更新一个log日志<br /> * yyyy-MM-dd-a: 每天的午夜和正午更新一个log日志 yyyy-MM-dd-HH: 每小时更新一个log日志<br /> * yyyy-MM-dd-HH-mm: 每分钟更新一个log日志<br /> */<br /> private static String update_hz = "yyyy-MM-dd";// 更新日志的频率,每月更新一次<br /> private static long max_log_size = 1024 * 1024 * 5;// 单个日志文件最大大小 5M<br /> //private static long max_log_size = 1024 * 2;// 单个日志文件最大大小 5M
    4. public static String getFinalPath(String rootpath,String secondpath){<br /> rootpath = StringUtils.trim(rootpath);<br /> secondpath = StringUtils.trim(secondpath);<br /> if(StringUtil.isEmpty(secondpath)) return rootpath;<br /> if(secondpath.startsWith("/")){<br /> secondpath = secondpath.substring(1);<br /> }<br /> if(!secondpath.endsWith("/")){<br /> secondpath += "/";<br /> }<br /> return rootpath + secondpath;<br /> }<br /> public static String getFinalName(String rootname,String secondname){<br /> rootname = StringUtils.trim(rootname);<br /> secondname = StringUtils.trim(secondname);<br /> if(StringUtil.isEmpty(secondname)) return rootname;<br /> return rootname + "-" + secondname;<br /> }<br /> /**<br /> * @author: qzf<br /> * @date: 2022/5/7 11:42<br /> * @describe:<br /> * @param: csv_secondpath 在根路径下面建立的二级路径,String csv_secondname 在主文件名后面建立的二级文件名<br /> * @return:<br /> */<br /> public static void log(String title,String content,String log_secondpath,String log_secondname) {<br /> runWrite(title,content, getFinalPath(csv_rootpath,log_secondpath), getFinalName(csv_rootname,log_secondname));<br /> }<br /> public static void log(String title,String content) {<br /> runWrite(title, content, getFinalPath(csv_rootpath,""), getFinalName(csv_rootname,""));<br /> }<br /> public static <T> void log(LinkedHashMap<String,Object> map, List<T> list, String log_secondpath, String log_secondname) {<br /> String title = getTitle(map);<br /> String content = getContent(map,list);<br /> runWrite(title, content, getFinalPath(csv_rootpath,log_secondpath), getFinalName(csv_rootname,log_secondname));<br /> }<br /> public static String getTitle(LinkedHashMap<String,Object> map){<br /> StringBuilder stringBuilder = new StringBuilder();<br /> //设置表头<br /> for (Map.Entry entry : map.entrySet()) {<br /> stringBuilder.append(entry.getKey().toString());<br /> stringBuilder.append("("+entry.getValue().toString()+")");<br /> stringBuilder.append(",");<br /> }<br /> return stringBuilder.toString();<br /> }<br /> public static <T> String getContent(LinkedHashMap<String,Object> map,List<T> list){<br /> StringBuilder stringBuilder = new StringBuilder();<br /> /*//设置表头 单独获取<br /> stringBuilder.append(getTitle(map));<br /> stringBuilder.append("\n\t");*/<br /> // 拼装excel内容<br /> T t = null;<br /> for (int i = 0; i < list.size(); i++) {<br /> t = (T)list.get(i);<br /> // 创建单元格,并设置值<br /> int j=0;<br /> for (Map.Entry entry : map.entrySet()) {<br /> int pos = j++;<br /> try {<br /> if (!entry.getValue().toString().contains(".")) {<br /> if(t.getClass().getName().equals("java.util.HashMap")){<br /> Object obj;<br /> obj = ((Map)t).get(entry.getValue().toString());<br /> if(obj.toString().equals("0E-10")) {<br /> stringBuilder.append("0");<br /> stringBuilder.append(",");<br /> }<br /> else {<br /> stringBuilder.append(obj == null ? "" :obj);<br /> stringBuilder.append(",");<br /> }<br /> } else {<br /> Field field = t.getClass().getDeclaredField(entry.getValue().toString());<br /> //设置对象的访问权限,保证对private的属性的访问<br /> field.setAccessible(true);<br /> stringBuilder.append(field.get(t) == null ? "" : field.get(t));<br /> stringBuilder.append(",");<br /> }<br /> } else {<br /> String[] arr = entry.getValue().toString().split("\\.");<br /> Object tmpObject = t;
    5. for (int k = 0; k < arr.length; k++) {<br /> if(t.getClass().getName().equals("java.util.HashMap")){<br /> if (k == arr.length - 1) {<br /> Object obj = ((Map)t).get(arr[k]);<br /> if(obj.toString().equals("0E-10")) {<br /> stringBuilder.append("0");<br /> stringBuilder.append(",");<br /> }<br /> else {<br /> stringBuilder.append(obj == null ? "" :obj);<br /> stringBuilder.append(",");<br /> }<br /> break;<br /> }<br /> } else {<br /> if (k == arr.length - 1) {<br /> Field tmpField = tmpObject.getClass().getDeclaredField(arr[k]);<br /> //设置对象的访问权限,保证对private的属性的访问<br /> tmpField.setAccessible(true);<br /> stringBuilder.append(tmpField.get(tmpObject) == null? "" : tmpField.get(tmpObject));<br /> stringBuilder.append(",");<br /> break;<br /> }
    6. Field field = tmpObject.getClass().getDeclaredField(arr[k]);<br /> //设置对象的访问权限,保证对private的属性的访问<br /> field.setAccessible(true);<br /> tmpObject = field.get(tmpObject);<br /> }<br /> }<br /> }<br /> }catch (Exception ex){<br /> ex.printStackTrace();<br /> }<br /> }//map<br /> stringBuilder.append("\n\t");<br /> }//list.size()<br /> return stringBuilder.toString();<br /> }<br /> /**<br /> * 写日志<br /> *<br /> * @param sWord<br /> * 要写入日志里的文本内容<br /> */<br /> public static void logResult(String title,String sWord, String logPath,String logName) {<br /> FileWriter writer = null;<br /> boolean flagNewFile = false;<br /> try {<br /> File dir = new File(logPath);<br /> if (!dir.exists()) {<br /> dir.mkdirs();<br /> }<br /> String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());<br /> File f = new File(logPath + logName + "-" + new SimpleDateFormat(update_hz).format(new Date()) + ".csv");<br /> if (!f.exists()) {<br /> f.createNewFile();<br /> flagNewFile = true;<br /> } else {<br /> long logSize = f.length();<br /> // 文件大小超过xxM,备份<br /> if (logSize >= max_log_size) {<br /> String backLogName = logPath + logName<br /> + new SimpleDateFormat("-yyyy-MM-dd-HHmmssSSS").format(new Date()) + ".csv";<br /> f.renameTo(new File(backLogName));<br /> }<br /> }<br /> writer = new FileWriter(f, true);
    7. BufferedWriter bufferedwriter = new BufferedWriter(writer);<br /> if(flagNewFile){<br /> bufferedwriter.write(title+"\n"+sWord);<br /> }<br /> else {<br /> bufferedwriter.write(sWord);<br /> }<br /> bufferedwriter.flush();<br /> } catch (Exception e) {<br /> System.out.println("记录csv日志异常:" + e.toString());<br /> log.error("记录csv日志异常:" + e.toString());<br /> e.printStackTrace();<br /> } finally {<br /> if (writer != null) {<br /> try {<br /> writer.close();<br /> } catch (IOException e) {<br /> e.printStackTrace();<br /> }<br /> }<br /> }<br /> }
    8. public static void runWrite(final String title,final String sWord,final String logPath, final String logName) {<br /> /*new Thread() {<br /> public void run() {<br /> logResult(sWord, logPath, logName);<br /> }<br /> }.start();;*/<br /> //线程池管理<br /> try {<br /> pool.execute(new Runnable() {<br /> @Override<br /> public void run() {<br /> logResult(title,sWord, logPath, logName);<br /> }<br /> });<br /> }<br /> catch (Exception e){<br /> e.printStackTrace();<br /> log.error("MyLogUtil记录日志出错"+e.getMessage());<br /> }<br /> }
    9. public static void main(String[] args) {<br /> for (int i = 0; i <1000; i++) {<br /> //log(""+i,"2022-04","Recv");<br /> log("",""+i);<br /> }<br /> }

    }