java操作csv文档通用工具类

本文介绍了一个用于处理CSV文件的Java工具类,该类提供了一系列通用方法,包括读取、写入和解析CSV文档,方便开发者在项目中进行数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package cn.com.test.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 自定义注解
* @author:  Rodge
* @time:    2017年12月25日 下午9:39:18
* @version: V1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CSVField {

	/**
     * CSV文件列名
     */
    public String name() default "";
       
}

 

csv工具类

 

package cn.com.javatest.utils;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.util.ReflectionUtils;

import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;

import cn.com.javatest.annotation.CSVField;

/**
 * CSV工具类
 * 
 * @author:  Rodge
 * @time:    2017年12月25日 下午10:02:08
 * @version: V1.0.0
 */
public final class CSVUtils {

	/** 日志对象 **/  
    private static final Logger LOGGER = Logger.getLogger(CSVUtils.class); 
    
    /** 临时文件**/ 
    private static final String TEMP_PATH = "temp.csv";
  
    /** 私有无参构造方法 **/  
    private CSVUtils() { }
    
    /** 
     * 生成CSV文件 
     * 
     * @param filePath 文件保存路径,例如:D:/temp/test.csv 
     * @param beans 实体对象集合 
     */  
    public static <T> void createCSVFile(String filePath, List<T> beans) {    
        CsvWriter writer = null;  
        try {  
            // 创建文件目录  
        	createDir(filePath);  
            // 生成文件  
            writer = new CsvWriter(filePath, ',', Charset.forName("GBK"));           
            // 获取内容  
            List<String[]> contents = getStringArrayFromBean(beans);   
            // 写入内容  
            for (String[] each : contents) {    
                writer.writeRecord(each, true);    
            }    
        } catch (Exception e) {  
            LOGGER.error("生成CSV文件失败", e);  
        } finally {  
            if (writer != null) {  
                writer.close();            
            }  
        }  
    }
    
    /** 
     * 导出CSV文件 
     * 
     * @param request 请求对象 
     * @param response 响应对象 
     * @param beans 实体对象集合 
     */  
    public static <T> void exportCSVFile(HttpServletRequest request, HttpServletResponse response, List<T> beans) {    
    	String path = request.getServletContext().getRealPath("/");
    	try (FileInputStream input = new FileInputStream(createFile(path + TEMP_PATH))) {  
    		// 生成文件  
    		CsvWriter writer = new CsvWriter(path + TEMP_PATH, ',', Charset.forName("GBK"));           
    		// 获取内容  
    		List<String[]> contents = getStringArrayFromBean(beans);   
    		// 写入内容  
    		for (String[] each : contents) {    
    			writer.writeRecord(each, true);    
    		}    
    		writer.close();
    		// 导出文件
    		ServletOutputStream output = response.getOutputStream();
    		// 以当前时间作为文件名  
            String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            response.setContentType("application/csv;charset=UTF-8");  
    		response.setHeader("Access-Control-Allow-Origin", "*");
    		response.setHeader("Access-Control-Expose-Headers", "*");
    		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".csv");
    		int len = -1;
    		byte[] b = new byte[1024 * 1024];
    		while((len = input.read(b)) != -1) {    
    			output.write(b, 0, len);
    		} 
    		output.close();
    	} catch (Exception e) {  
    		LOGGER.error("导出CSV文件失败", e);  
    	} finally {  
    		deleteFile(path, TEMP_PATH);
    	}  
    }
    
    /** 
     * 导出CSV文件 
     * 
     * @param request 请求对象 
     * @param response 响应对象 
     * @param beans 实体对象集合 
     * @param fileName 文件名称 ,如:测试名称 
     */  
    public static <T> void exportCSVFile(HttpServletRequest request, HttpServletResponse response, List<T> beans, String fileName) {    
    	String path = request.getServletContext().getRealPath("/");
    	try (FileInputStream input = new FileInputStream(createFile(path + TEMP_PATH))) {  
    		// 生成文件  
    		CsvWriter writer = new CsvWriter(path + TEMP_PATH, ',', Charset.forName("GBK"));           
    		// 获取内容  
    		List<String[]> contents = getStringArrayFromBean(beans);   
    		// 写入内容  
    		for (String[] each : contents) {    
    			writer.writeRecord(each, true);    
    		}    
    		writer.close();
    		// 导出文件
    		ServletOutputStream output = response.getOutputStream();
    		response.setContentType("application/csv;charset=UTF-8");  
    		response.setHeader("Access-Control-Allow-Origin", "*");
    		response.setHeader("Access-Control-Expose-Headers", "*");
    		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".csv");
    		int len = -1;
    		byte[] b = new byte[1024 * 1024];
    		while((len = input.read(b)) != -1) {    
    			output.write(b, 0, len);
    		} 
    		output.close();
    	} catch (Exception e) {  
    		LOGGER.error("导出CSV文件失败", e);  
    	} finally {  
    		deleteFile(path, TEMP_PATH);
    	}  
    }
    
    /**
     * 导出CSV模板
     * 
     * @param request 请求对象
     * @param response 响应对象
     * @param beans 实体对象集合
     */
    public static <T> void exportCSVTemplate(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
    	// 以当前时间作为文件名  
    	String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    	exportCSVTemplate(request, response, clazz, fileName);
    }
    
    /**
     * 导出CSV模板
     * 
     * @param request 请求对象
     * @param response 响应对象
     * @param beans 实体对象集合
     * @param fileName 文件名称
     */
    public static <T> void exportCSVTemplate(HttpServletRequest request, HttpServletResponse response, Class<T> clazz, String fileName) {
    	String path = request.getServletContext().getRealPath("/");
    	try (FileInputStream input = new FileInputStream(createFile(path + TEMP_PATH))) {  
    		// 生成文件  
    		CsvWriter writer = new CsvWriter(path + TEMP_PATH, ',', Charset.forName("GBK"));           
    		// 筛选出标有注解的字段  
    		Field[] declaredFields = clazz.getDeclaredFields();    
    		List<Field> annoFields = new ArrayList<Field>();     
    		for (Field field : declaredFields) {  
    			CSVField anno = field.getAnnotation(CSVField.class);    
    			if (anno != null) {   
    				annoFields.add(field);    
    			}  
    		}
    		// 获取注解的值,即内容标题  
    		String[] title = new String[annoFields.size()];       
    		for (int i = 0; i < annoFields.size(); i++) {    
    			title[i] = annoFields.get(i).getAnnotation(CSVField.class).name();    
    		}
    		// 写入内容  
    		if (ArrayUtils.isNotEmpty(title)) {
    			writer.writeRecord(title); 
    		}
    		writer.close();
    		// 导出文件
    		ServletOutputStream output = response.getOutputStream();
    		response.setContentType("application/csv;charset=UTF-8");  
    		response.setHeader("Access-Control-Allow-Origin", "*");
    		response.setHeader("Access-Control-Expose-Headers", "*");
    		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".csv");
    		int len = -1;
    		byte[] b = new byte[1024 * 1024];
    		while((len = input.read(b)) != -1) {    
    			output.write(b, 0, len);
    		} 
    		output.close();
    	} catch (Exception e) {  
    		LOGGER.error("导出CSV模板失败", e);  
    	} finally {  
    		deleteFile(path, TEMP_PATH);
    	}
    }
  
    /** 
     * 读取CSV文件内容 
     *  
     * @param filePath 文件存放的路径,如:D:/csv/xxx.csv 
     * @param bean 类类型 
     * @return List<T> 
     */  
    public static <T> List<T> readCSVFile(String filePath, Class<T> bean) {  
        List<String[]> dataList = new ArrayList<String[]>();    
        CsvReader reader = null;  
        try {    
            // 创建CSV读对象 例如:CsvReader(文件路径,分隔符,编码格式);    
            reader = new CsvReader(filePath, ',', Charset.forName("GBK"));    
            if (reader != null) {  
                // 跳过表头,如果需要表头的话,这句可以忽略    
                //reader.readHeaders();    
                // 逐行读入除表头的数据    
                while (reader.readRecord()) {    
                    dataList.add(reader.getValues());     
                }    
                if (!dataList.isEmpty()) {  
                    // 数组转对象  
                    return getBeanFromStringArray(dataList, bean);  
                }  
            }  
        } catch (Exception e) {    
            LOGGER.error("读取CSV文件失败", e);    
        } finally {  
            if (reader != null) {  
                reader.close();   
            }  
        }  
        return Collections.emptyList();  
    }  
    
    /** 
     * 删除该目录下所有文件 
     * 
     * @param filePath 文件目录路径,如:d:/test 
     */  
    public static boolean deleteFiles(String filePath) {  
        File file = new File(filePath);  
        if (file.exists()) {  
            File[] files = file.listFiles();  
            if (files != null && files.length > 0) {  
                for (File f : files) {  
                    if (f.isFile() && f.delete()) {  
                        LOGGER.info("删除" + f.getName() + "文件成功");  
                    }  
                }  
                return true;  
            }  
        }  
        return false;  
    }  
  
    /** 
     * 删除单个文件 
     * 
     * @param filePath 文件目录路径,如:d:/test 
     * @param fileName 文件名称,如:110.csv 
     */  
    public static boolean deleteFile(String filePath, String fileName) {  
        File file = new File(filePath);  
        if (file.exists()) {  
            File[] files = file.listFiles();  
            if (files != null && files.length > 0) {  
                for (File f : files) {  
                    if (f.isFile() && f.getName().equals(fileName)) {  
                        return f.delete();  
                    }  
                }  
            }  
        }  
        return false;  
    }  
      
    /** 
     * 泛型实体转换为数组 
     * 
     * @param beans 实体类集合
     * @return List<String[]> 
     */  
    private static <T> List<String[]> getStringArrayFromBean(List<T> beans) {     
        List<String[]> result = new ArrayList<String[]>();          
        Class<? extends Object> cls = beans.get(0).getClass();    
        Field[] declaredFields = cls.getDeclaredFields();    
        List<Field> annoFields = new ArrayList<Field>();     
        // 筛选出标有注解的字段  
        for (Field field : declaredFields) {  
            CSVField anno = field.getAnnotation(CSVField.class);    
            if (anno != null) {   
                annoFields.add(field);    
            }  
        }   
        // 获取注解的值,即内容标题  
        String[] title = new String[annoFields.size()];       
        for (int i = 0; i < annoFields.size(); i++) {    
            title[i] = annoFields.get(i).getAnnotation(CSVField.class).name();    
        }    
        result.add(title);    
        try {  
            // 获取内容  
            for (T t : beans) {    
                String[] item = new String[annoFields.size()];   
                int index = 0;  
                for (Field field : annoFields) {  
                	Class<?> valType = field.getType();
                    String fieldName = field.getName();  
                    String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);    
                    Method method = ReflectionUtils.findMethod(t.getClass(), methodName);  
                    if (method != null) {  
                        Object value = ReflectionUtils.invokeMethod(method, t);  
                        item[index] = setValues(value, valType);
                    }   
                    index ++;  
                }  
                result.add(item);           
            }  
        } catch (Exception e) {  
            LOGGER.info("实体对象转数组失败", e);  
        }    
        return result;    
    }  
      
    /** 
     * 数组转为对象集合 
     * 
     * @param dataList 集合数据
     * @param bean 类类型
     * @return List<T> 
     */  
    private static <T> List<T> getBeanFromStringArray(List<String[]> dataList, Class<T> bean) {  
        List<T> list = new ArrayList<>();  
        List<Map<String, String>> titles = getTitles(dataList);  
        Map<String, Field> fields = getFields(bean);  
        try {  
            for (Map<String, String> map : titles) {  
                T t = bean.newInstance();  
                for (Entry<String, String> entry : map.entrySet()) {  
                    if (fields.containsKey(entry.getKey())) {  
                        Field field = fields.get(entry.getKey());  
                        Class<?> valType = field.getType(); 
                        Object value = getType(entry.getValue(), valType);
                        String fieldName = field.getName();                                                     
                        String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);    
                        Method method = ReflectionUtils.findMethod(bean, methodName, valType);  
                        if (method != null) {  
                            ReflectionUtils.invokeMethod(method, t, value);  
                        }  
                    }  
                }  
                list.add(t);  
            }  
        } catch (Exception e) {  
            LOGGER.error("创建实体失败", e);  
        }  
        return list;  
    }  
      
    /** 
     * 数组标题与值的对应关系 
     * 
     * @param dataList 集合数据
     * @return 
     */  
    private static <T> List<Map<String, String>> getTitles(List<String[]> dataList) {  
        List<Map<String, String>> list = new ArrayList<>();  
        String[] titles = dataList.get(0);  
        dataList.remove(0);  
        for (String[] values : dataList) {  
            Map<String, String> titleMap = new HashMap<>();  
            for (int i = 0; i < values.length; i++) {  
                titleMap.put(titles[i], values[i]);  
            }  
            list.add(titleMap);  
        }  
        return list;  
    }  
      
    /** 
     * 注解名称与字段属性的对应关系 
     *   
     * @param clazz 实体对象类类型 
     * @param <T> 泛型类型 
     * @return Map<String,Field> 
     */  
    private static <T> Map<String, Field> getFields(Class<T> clazz) {  
        Map<String, Field> annoMap = new HashMap<>();  
        Field[] fileds = clazz.getDeclaredFields();  
        for (Field filed : fileds) {  
            CSVField anno = filed.getAnnotation(CSVField.class);  
            if (anno != null) {  
                // 获取name属性值  
                if (StringUtils.isNotBlank(anno.name())) {  
                    annoMap.put(anno.name(), filed);  
                }  
            }  
        }  
        return annoMap;  
    }
    
    /**
     * 转换值
     * 
     * @param value 属性值
     * @param valType 属性类型
     * @return
     */
    private static String setValues(Object value, Class<?> valType) {
    	if (value == null) {                            
            return "";  
        } else if (valType == Date.class) {
        	// 默认日期类型格式:yyyy-MM-dd HH:mm:ss
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
            return sdf.format(((Date) value).getTime());  
            
        } else { // 字符串  
        	return String.valueOf(value);  
        }
    }
    
    /** 
     * 转换成实体属性对应的类型 
     *   
     * @param value 每一格的数值 
     * @param valType 实体属性类型 
     * @return Object 转换为对应类型以obj返回 
     */  
    private static <T> Object getType(String value, Class<T> valType) {  
        try {  
            if (valType == Date.class) {   
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                return sdf.parse(value);  
            } else if (valType == Double.class) {    
                return Double.parseDouble(value);    
            } else if (valType == BigDecimal.class) {    
                return new BigDecimal(value);    
            } else if (valType == Integer.class) {    
                return Integer.parseInt(value);    
            } else if (valType == Long.class) {    
                return Long.parseLong(value);    
            } else if (valType == Boolean.class) {    
                return Boolean.parseBoolean(value);    
            }   
        } catch (Exception e) {  
            LOGGER.error("类型转换异常", e);  
        }  
        return value;    
    }
        
    /** 
     * 创建文件目录
     * 
     * @param filePath 文件路径,例如:temp/test.csv 
     */  
    private static void createDir(String filePath) {  
        try {  
        	File file = new File(filePath.substring(0, filePath.lastIndexOf('/')));  
            if (!file.exists()) {  
                file.mkdirs();  
            }         
        } catch (Exception e) {  
            LOGGER.error("创建文件目录失败", e);  
        }  
    }  
    
    /** 
     * 创建文件
     * 
     * @param filePath 文件路径,例如:temp/test.csv 
     * @return File 
     */  
    private static File createFile(String filePath) {  
    	try {  
    		File file = new File(filePath);  
    		if (!file.exists()) {
    			file.createNewFile();
    		} 
    		return file;
    	} catch (Exception e) {  
    		LOGGER.error("创建文件失败", e);  
    	} 
    	return null;
    }  
    
}

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值