實現excel導入導出功能,excel導入數據到頁面中,頁面數據導出生成excel文件


今天接到項目中的一個功能,要實現excel的導入,導出功能。這個看起來思路比較清楚,但是做起了就遇到了不少問題。

不過核心的問題,大家也不會遇到了。每個項目前台頁面,以及數據填充方式都不一樣,不過大多都是以json數據填充的。在導入excel填充json數據到頁面時,真的讓我差點吐血了。在做這個導入導出的時候,那一個禮拜都是黑暗的。

好了,廢話不多說了,我今天就給大家展示這個兩個功能的核心點,excel生成json數據和json數據生成excel文件。

一:從上傳文件到服務器,后台java解析,返回excel的json數據到前台。我自己從新做了一個簡單的測試項目,需要演示項目的(struts2),下面評論出來,謝謝大家支持。

1.excel生成json數據,用於導入excel文件到頁面中。

2.可以使用jxl,或者poi去實現這個,我兩種方式都采用了,下面是jar包(標記的jar是核心excel轉json數據的,包括jxl和poi,其它jar是項目的)

 3.還是和上傳文件一樣,使用ajax,formdata對象將文件傳輸到后台,此時生成的是二進制文件,需要在服務器上生成所要的文件。

4.調用方法將上傳的文件轉化為json數據,使用poi要注意了,03版和07版使用的對象不一樣,代碼中有說明。

4.將得到的json數據返回前台。

5.下面是效果圖,最后面就附上源碼。

這是后台java處理代碼。

package com.pan.files.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;
/*import org.springframework.web.multipart.MultipartFile;*/
 


public class ImportExcel  {

	private File  files; //上傳的文件路徑
	private String filesFileName; //文件名
	
	
	
	

	public File getFiles() {
		return files;
	}


	public void setFiles(File files) {
		this.files = files;
	}


	public String getFilesFileName() {
		return filesFileName;
	}


	public void setFilesFileName(String filesFileName) {
		this.filesFileName = filesFileName;
	}
  /*
	這個是jxl方式
	dir:文件地址
	
  */
	/*public static String excelToJson(File dir ) throws BiffException, IOException {  
                jxl.Workbook wb =jxl.Workbook.getWorkbook(dir); // 從文件流中獲取Excel工作區對象(WorkBook)  
                jxl.Sheet sheet = wb.getSheet(0); // 從工作區中取得頁(Sheet)  
                jxl.Cell[] header = sheet.getRow(0);  
                String json1 = "";
                String[] arry = new String[sheet.getRows()];
                for (int i = 1; i < sheet.getRows(); i++) { // 循環打印Excel表中的內容  
                    Map hashMap = new HashMap();
                    ArrayList List = new ArrayList();
                    for (int j = 0; j < sheet.getColumns(); j++) {  
                    	jxl.Cell cell = sheet.getCell(j, i);  
                        List.add(cell.getContents()); 
                    }  
                    // 這個json字符串就是我們想要的,實際應用中可以直接返回該字符串  
                   // String json = JSONObject.toJSONString(hashMap); 
                //    String json = JSONObject.toJSONString(List); 
                    String json = com.alibaba.fastjson.JSONArray.toJSONString(List); 
                    json1 += json+",";
                
                } 
  
              
                return "["+ json1.substring(0,json1.length()-1)+"]excel";
            } */
	
	  
	    public  void targetFile() throws Exception { 
	        //根據服務器的文件保存地址和原文件名創建目錄文件全路徑 
	        String dirs= ServletActionContext.getServletContext() 
                    .getRealPath("/image");
	        if (files != null){
	            File savedir = new File(dirs) ;
	            if (! savedir.exists()) {
	                savedir.mkdirs() ;
	            }
	        }
	       //將上傳到服務器上的二進制文件寫成實際文件
	           File savefile = new File(dirs, filesFileName); 
	           FileUtils.copyFile(files, savefile) ;
	       //      String paremt =  excelToJson(savefile);
	     LinkedHashMap<String, String> sjson =   excelTojson(savefile);
	           HttpServletResponse response = ServletActionContext.getResponse();
	           response.setHeader("Content-type", "text/html;charset=UTF-8");  
	         //這句話的意思,是告訴servlet用UTF-8轉碼,而不是用默認的ISO8859  
	         response.setCharacterEncoding("UTF-8");  
	           PrintWriter out = response.getWriter();
	//        copy(this.files, di); 
	         out.println(sjson);
	    } 
	   
	    public static LinkedHashMap<String,String> excelTojson(File file) throws IOException, Exception {
	        // 返回的map
	        LinkedHashMap<String,String> excelMap = new LinkedHashMap<>();
	        // Excel列的樣式,主要是為了解決Excel數字科學計數的問題
	        CellStyle cellStyle;
	        // 根據Excel構成的對象
	        Workbook wb;
	        // 如果是2007及以上版本,則使用想要的Workbook以及CellStyle
	        if(file.getName().endsWith("xlsx")){   //07及07以后版本
	            wb = new XSSFWorkbook(new FileInputStream(file));
	            XSSFDataFormat dataFormat = (XSSFDataFormat) wb.createDataFormat();
	            cellStyle = wb.createCellStyle();
	            // 設置Excel列的樣式為文本
	            cellStyle.setDataFormat(dataFormat.getFormat("@"));
	        }else{    //03版本
	            POIFSFileSystem fs = new POIFSFileSystem(file);
	            wb = new HSSFWorkbook(fs);
	            HSSFDataFormat dataFormat = (HSSFDataFormat) wb.createDataFormat();
	            cellStyle = wb.createCellStyle();
	            // 設置Excel列的樣式為文本
	            cellStyle.setDataFormat(dataFormat.getFormat("@"));
	        }
	 
	        // sheet表個數
	        int sheetsCounts = wb.getNumberOfSheets();
	        // 遍歷每一個sheet
	        for (int i = 0; i < sheetsCounts; i++) {
	            Sheet sheet = wb.getSheetAt(i);
	            // 一個sheet表對於一個List
	            List list = new LinkedList();
	            // 將第一行的列值作為正個json的key
	            String[] cellNames;
	            // 取第一行列的值作為key
	            Row fisrtRow = sheet.getRow(0);
	            // 如果第一行就為空,則是空sheet表,該表跳過
	            if(null == fisrtRow){
	                continue;
	            }
	            // 得到第一行有多少列
	            int curCellNum = fisrtRow.getLastCellNum();
	            // 根據第一行的列數來生成列頭數組
	            cellNames = new String[curCellNum];
	            // 單獨處理第一行,取出第一行的每個列值放在數組中,就得到了整張表的JSON的key
	            for (int m = 0; m < curCellNum; m++) {
	                Cell cell = fisrtRow.getCell(m);
	                // 設置該列的樣式是字符串
	                cell.setCellStyle(cellStyle);
	                cell.setCellType(Cell.CELL_TYPE_STRING);
	                // 取得該列的字符串值
	                cellNames[m] = cell.getStringCellValue();
	            }
	            for (String s : cellNames) {
	            }
	 
	            // 從第二行起遍歷每一行
	            int rowNum = sheet.getLastRowNum();
	            System.out.println("總共有 " + rowNum + " 行");
	            for (int j = 1; j <= rowNum; j++) {
	                // 一行數據對於一個Map
	                LinkedHashMap rowMap = new LinkedHashMap();
	                // 取得某一行
	                Row row = sheet.getRow(j);
	                int cellNum = row.getLastCellNum();
	                // 遍歷每一列
	                for (int k = 0; k < cellNum; k++) {
	                    Cell cell = row.getCell(k);
	 
	                    cell.setCellStyle(cellStyle);
	                    cell.setCellType(Cell.CELL_TYPE_STRING);
	                    // 保存該單元格的數據到該行中
	        rowMap.put(cellNames[k],cell.getStringCellValue());
	                }
	                // 保存該行的數據到該表的List中
	                list.add(rowMap);
	            }
	            // 將該sheet表的表名為key,List轉為json后的字符串為Value進行存儲
	            excelMap.put(sheet.getSheetName(),JSON.toJSONString(list,false));
	        }
	        wb.close();
	        return excelMap;
	    }
	 
	
	   
	      
	    public static void main(String [] args) throws FileNotFoundException{
	   // 	createJson();
	    	
	    }
	}   
	
	
	
	

 這是前台js文件:

$(function () {

	$("#confirm").on("click",function(){
		var files =  $("input").eq(0).val();
		if(files==""){
			alert("請先上傳文件");
		}
	});
	$("#cancel").on("click",function(){
	//	webform.close();
	});

	$("#fileUpload").change(function(){ 
		var val = $(this).val();
		var fileName  = val.split("\\")[val.split("\\").length-1];
		if (val.indexOf("xls") != -1 || val.indexOf("xlsx") != -1) {
			$("input").eq(0).val(fileName);
	
			$('#formFile').ajaxSubmit({
				url:'excel_targetFile.action',
				type:'POST',
			//	data:{scmd:''}, 需要傳什么參數自己配置
				success:function(data){

					$("#confirm").on("click",function(){

					
						alert("導入成功");
					});
					$("#cancel").on("click",function(){

						alert("取消導入");
					});
				},
				error:function(xhr){
				      alert("上傳出錯");
				}                              
			});

		} else {
			alert("請選擇正確的文件格式!");
			//清空上傳路徑
			$(this).val("");
			return false;
		}

	});



	
	
})

  這是jsp頁面代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="./js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="./js/jquery.form.js" type="text/javascript"></script>
<script src="./js/excelJs.js" type="text/javascript"></script>
<style type="text/css">
.file {
    position: relative;
    display: inline-block;
    background: #D0EEFF;
    border: 1px solid #99D3F5;
    border-radius: 4px;
  /*   padding: 4px 12px; */
    overflow: hidden;
    color: #1E88C7;
    text-decoration: none;
    text-indent: 0;
    line-height: 20px;
    top:6px;
}
.file input {
    position: absolute;
    font-size: 100px;
    right: 0;
    top: 0;
    opacity: 0;
} 
.file:hover {
    background: #AADFFD;
    border-color: #78C3F3;
    color: #004974;
    text-decoration: none;
}
.positionFile{
margin-left: 10px;
margin-top: 30px;
}
.poConfirm{
margin-top: 40px;
margin-left: 65px;
}

</style>
</head>
<body >

<form id="formFile">
<input id="textId" type="text" value="" class="positionFile"  readonly="readonly">
<a href="javascript:;" class="file">點擊上傳文件
<input type="file" id="fileUpload" name="files" >
</a>
<br>
<input type="button" id="confirm" value="確定" class="co-win-button poConfirm">
<input type="button" id="cancel" value="取消" class="co-win-button poConfirm">
</form>
</body>
</html>

  

好啦,到這里你以及看完了整個過程,重點是要理解其中的思路,尤其是轉化方法上面。下面我將介紹導出json數據到excel文件中,其實這個就簡單了就在后台將你的json數據調用轉化方法,然后寫入到excel文件中,返回前台設置響應讓其下載即可。

這個是導出excel核心的方法。

   /* 
	    src:定義下載的文件路徑   
	*/
	    public static JSONObject createExcel(String src, JSONArray json) {
	        JSONObject result = new JSONObject(); // 用來反饋函數調用結果
	        try {
	            // 新建文件
	            File file = new File(src);
	            file.createNewFile();

	            OutputStream outputStream = new FileOutputStream(file);// 創建工作薄
	            jxl.write.WritableWorkbook writableWorkbook = jxl.Workbook.createWorkbook(outputStream);
	            jxl.write.WritableSheet sheet = writableWorkbook.createSheet("First sheet", 0);// 創建新的一頁

//	            JSONArray jsonArray = json.getJSONArray("dt");// 得到data對應的JSONArray
	            JSONArray jsonArray = json;// 得到data對應的JSONArray
	            jxl.write.Label label; // 單元格對象
	            int column = 0; // 列數計數

	            // 將第一行信息加到頁中。如:姓名、年齡、性別
	            JSONObject first = jsonArray.getJSONObject(0);
	            Iterator<String> iterator = first.keys(); // 得到第一項的key集合
	            while (iterator.hasNext()) { // 遍歷key集合
	                String key = (String) iterator.next(); // 得到key
	                label = new jxl.write.Label(column++, 0, key); // 第一個參數是單元格所在列,第二個參數是單元格所在行,第三個參數是值
	                sheet.addCell(label); // 將單元格加到頁
	            }

	            // 遍歷jsonArray
	            for (int i = 0; i < jsonArray.size(); i++) {
	                JSONObject item = jsonArray.getJSONObject(i); // 得到數組的每項
	                iterator = item.keys(); // 得到key集合
	                column = 0;// 從第0列開始放
	                while (iterator.hasNext()) {
	                    String key = iterator.next(); // 得到key
	                    String value = item.getString(key); // 得到key對應的value
	                    label = new jxl.write.Label(column++, (i + 1), value); // 第一個參數是單元格所在列,第二個參數是單元格所在行,第三個參數是值
	                    sheet.addCell(label); // 將單元格加到頁
	                }
	            }
	            writableWorkbook.write(); // 加入到文件中
	            writableWorkbook.close(); // 關閉文件,釋放資源
	        } catch (Exception e) {
	            result.put("result", "failed"); // 將調用該函數的結果返回
	            result.put("reason", e.getMessage()); // 將調用該函數失敗的原因返回
	            return result;
	        }

//	        result.put("result", "successed");
	        return result;
	    }

  

 雖然在項目運用到了這個,昨天自己又從新搭建項目給大家提供一個演示例子,真的又彌補到了很多東西,包括struts2的配置請求方式,json數據轉化解析過程,ajax請求機制,poi對excel,word等文件編輯操作等等。如果大家覺得可以請點個贊,你們的贊是我前進的動力。

另外大神們看了有什么問題請指出來,我虛心學習,需要演示項目源碼的就在下方評論出來,大家一起分享學習。

 

需要演示項目的到我github上下載, https://github.com/chenpanpan0809/MyProjcet

別忘了點波推薦哦,大神們(*^_^*)

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM