html+Java 结合的CSV导入导出

在自己项目中有涉及到CSV导入导出的功能,自己通过查询资料和修改,总结了一份使用模板,仅作为参考。

导入

<div>
	<input name="file" id="file" type="file"  accept=".csv" onchange="changeFile" style="display: none;">
	<button type="button" class="btn btn-default " onclick="$('#file').click()">上传文件</button>
</div>

@change 方法是使用的vue监听了文件改变事件,可以做一些类似于文件大小判断的操作等。

function changeFile(event){
     	if(event.target.files[0].size>1024*1024*2){
     		alert("单个文件不超过2M");
     		return;
     	}
     	console.log(event.target.files[0].name+"("+bytesToSize(event.target.files[0].size)+")");                                   
			
     }
//根据byte 转换容量
	function bytesToSize(bytes) {  
		  if (bytes === 0) return '0 B';  
		  var k = 1024, // or 1024  
		  sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],  
		  i = Math.floor(Math.log(bytes) / Math.log(k));  
		  return (bytes / Math.pow(k, i)).toPrecision(3) + sizes[i];  
	}  

科普一下files都包含哪些内容

name: 本地文件的名称  
size: 文件的字节大小  
type: 字符、文件的MIME类型  
lastModifiedDate: 文件上次修改的时间(chrome实现了这属性)

Files api 可以参考这篇博文https://blog.csdn.net/jyy_12/article/details/9851349

言归正传,接下来是js上传文件的操作

       var $form = new FormData($('#form')[0]); 
        $.ajax({
                url: 'xxx/importCsv' ,
                type: 'post',
                data: $form,
                processData:false,
                contentType:false,
                success:function(data){
                    //根据自己情况修改返回参数和做处理
                	if (data.code == '500') {
                		$("#file").val("");
						alert(data.msg);
					} else if (data.code == '0') {
						alert("成功!");
					}
                	
                },
                error:function(e){
                	alert("读取失败");
                	
                }
           });

 formdata用法详解请参考 https://blog.csdn.net/zqian1994/article/details/79635413

Java部分

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Method;
import java.util.*;

public class CSVUtils {
    /**
     * @param response
     * @param map   对应的列标题
     * @param exportData    需要导出的数据
     * @param fileds    列标题对应的实体类的属性
     * @throws IOException
     */
    @SuppressWarnings({ "resource", "rawtypes", "unchecked" })
    public static void exportFile(HttpServletResponse response, HashMap map, List exportData, String[] fileds)throws IOException {
        try {
            // 写入临时文件
            File tempFile = File.createTempFile("vehicle", ".csv");
            BufferedWriter csvFileOutputStream = null;
            // UTF-8使正确读取分隔符","
            csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "GBK"), 1024);
            // 写入文件头部
            for (Iterator propertyIterator = map.entrySet().iterator(); propertyIterator.hasNext();) {
                java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();
                csvFileOutputStream.write((String) propertyEntry.getValue() != null ? new String(((String) propertyEntry.getValue()).getBytes("GBK"), "GBK") : "");
                if (propertyIterator.hasNext()) {
                    csvFileOutputStream.write(",");
                }
            }
            csvFileOutputStream.write("\r\n");
            // 写入文件内容,
            // ============ //:Arraylist<实体类>填充实体类的基本信息==================
            for (int j = 0; exportData != null && !exportData.isEmpty() && j < exportData.size(); j++) {

                Class clazz = exportData.get(j).getClass();
                String[] contents = new String[fileds.length];
                for (int i = 0; fileds != null && i < fileds.length; i++) {
                    String filedName = toUpperCaseFirstOne(fileds[i]);
                    Object obj = null;
                    try {
                        Method method = clazz.getMethod(filedName);
                        method.setAccessible(true);
                        obj = method.invoke(exportData.get(j));
                    } catch (Exception e) {

                    }
                    String str = String.valueOf(obj);
                    if (str == null || str.equals("null")) {
                        str = "";
                    }
                    contents[i] = str;
                }

                for (int n = 0; n < contents.length; n++) {
                    // 将生成的单元格添加到工作表中
                    csvFileOutputStream.write(contents[n]);
                    csvFileOutputStream.write(",");
                }
                csvFileOutputStream.write("\r\n");
            }

            csvFileOutputStream.flush();

            /**
             * 写入csv结束,写出流
             */
            java.io.OutputStream out = response.getOutputStream();
            byte[] b = new byte[10240];
            java.io.File fileLoad = new java.io.File(tempFile.getCanonicalPath());
            response.reset();
            response.setContentType("application/csv");
            String trueCSVName= UUID.randomUUID()+ ".csv";
            response.setHeader("Content-Disposition", "attachment;  filename="+ new String(trueCSVName.getBytes("GBK"), "ISO8859-1"));
            long fileLength = fileLoad.length();
            String length1 = String.valueOf(fileLength);
            response.setHeader("Content_Length", length1);
            java.io.FileInputStream in = new java.io.FileInputStream(fileLoad);
            int n;
            while ((n = in.read(b)) != -1) {
                // 每次写入out1024字节
                out.write(b, 0, n);
            }
            in.close();
            out.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static String toUpperCaseFirstOne(String origin) {
        StringBuffer sb = new StringBuffer(origin);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        sb.insert(0, "get");
        return sb.toString();
    }



    /**
     * 导入
     *
     * @param file
     *          csv文件(路径+文件)
     * @return
     */
    public static List<String> importCsv(MultipartFile file){
        List<String> dataList = new ArrayList<String>();
        BufferedReader br = null;
        try{

            br =  new BufferedReader(new InputStreamReader(file.getInputStream(), "UTF-8"));
            String line ;
            while((line = br.readLine()) != null)
            {
                dataList.add(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if (br != null){
                try{
                    br.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        return dataList;
    }

}
@RequestMapping("importCsv")
@ResponseBody
public ProtocolResponse importCsv(MultipartFile file)throws ServletException,IOException{
         try {
            List<String> lineList= CSVUtils.importCsv(file);
            if(null==lineList||!lineList.get(0).split(",")[0].equals("DeviceName")){
                //此处做了一个标头判断 判断第一个名称是不是DeviceName
                return  ProtocolResponse.errorResponse("文件无数据或格式错误!");
            }
             //移除表头
            lineList.remove(0);
            if(lineList.size()>max){
                return  ProtocolResponse.errorResponse("文件数据最多包含1000条记录!");
            }
            
            for (String s:lineList){//遍历每一行的数据
                //每一行的数据都是以逗号区分,所以可以通过这种方式获取到每一个导入数据
                String[] name=s.split(",");
                //其他数据操作,比如判断数据合不合标准,错误数据的数量等等,最后以map形式返回出去
            }
            

             return  ProtocolResponse.successResponse("操作成功");
         }catch (Exception e){
            e.printStackTrace();
            return  ProtocolResponse.errorResponse(MsgConstant.MSG_OPERATION_FAILED);
        }



 }

导出

Java导出

@RequestMapping(path="/export")
public void export(HttpServletRequest request, HttpServletResponse response) {
        String ids=request.getParameter("ids");
        if(StringUtils.isEmpty(ids)){
            return;
        }
        try {

            List<DeviceEntity> exportData= deviceManager.select(ids);
            if(null==exportData){
                return;
            }
          
            HashMap map = new LinkedHashMap();
            //表头
            map.put("1", "名称");
            map.put("2", "描述");
           //对应字段
            String[] fileds = new String[] { "name", "des"};
            CSVUtils.exportFile(response, map, exportData, fileds);
        }catch (Exception e){
            e.printStackTrace();
            return;
        }

    }

js代码导出模板

<a onclick="model" style="color: #5bc0de;cursor: pointer;">下载.csv模板</a>
    function model(){
			var str = "Name,Id";  
	         str =  encodeURIComponent(str);  
			 var aLink = document.createElement("a");
	         aLink.href = "data:text/csv;charset=utf-8,\ufeff"+str;  
			 aLink.download="Template.csv";
	         aLink.click();  
			aLink.remove();
     }

js导出的时候每一行的数据用逗号间隔,不同行数据用"\n"间隔,切记切记!

猜你喜欢

转载自blog.csdn.net/u013868665/article/details/84562175
今日推荐