实现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
别忘了点波推荐哦,大神们(*^_^*)
实现excel导入导出功能,excel导入数据到页面中,页面数据导出生成excel文件的更多相关文章
- 将页面中表格数据导出excel格式的文件(vue)
近期由于项目需要,需要将页面中的表格数据导出excel格式的文件,折腾了许久,在网上各种百度,虽然资料不少,但是大都不全,踩了许多坑,总算是皇天不负有心人,最后圆满解决了. 1.安装相关依赖(npm安 ...
- SQL Server导入数据报错"无法在只读列“Id”中插入数据"
使用sql server 导入数据报错:无法在只读列'id'中插入数据.如下图所示: 查找出现该问题的原因是表中id为自动增长的标识列,需要在[编辑映射]中勾选"启用标识插入": ...
- JS将页面中表格,导出到Excel中(IE中)
原文地址:http://blog.csdn.net/sinat_15114467/article/details/51098522 var idTmr; function getExplorer() ...
- mysql数据库导出模型到powerdesigner,PDM图形窗口中显示数据列的中文注释
1,mysql数据库导出模型到powerdesigner 2,CRL+Shift+X 3,复制以下内容,执行 '******************************************** ...
- Struts2(三)——数据在框架中的数据流转问题
一款软件,无在乎对数据的处理.而B/S软件,一般都是用户通过浏览器客户端输入数据,传递到服务器,服务器进行相关处理,然后返回到指定的页面,进行相关显示,完成相关功能.这篇博客重点简述一下Struts2 ...
- 读取控制器PHP代码文件,并分析数据存到数据库,再重新读出生成PHP文件
<?php namespace app\publicSport\controller\verify; /** * 引入基类 */ use app\publicSport\controller ...
- PHP 页面中实现数据的增删改查
main页面(主页面) <table width="100%" border="1" cellpadding="0" cellspac ...
- Vue2.0---将页面中表格数据导出excel
这不是教程,是随笔. 项目中将后台返回的数据v-for到表格中,然后需要将这个表格导出为EXCEL 只说怎么做. 一.需要安装三个依赖: npm install -S file-saver xlsx ...
- 得到 window.open 新页面中的数据
1.htm 页面 单击按 '钮后' 调用window.open方法,开启新窗口 2.htm 想实现---------------------- 在2.htm页面单击按钮 将相应的数据返回到 1. ...
- 使用springmvc从页面中获取数据,然后根据获得的参数信息进行修改,如果修改的数据中含有不是基本数据类型的参数。比如传的参数中有Date类型的数据时,需要我们进行参数类型转换。
1.1 需求 在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式. 1.2 需求分析 由于日期数据有很多格式,所以springmvc没办法把字符串转换成日期类型.所以需要自定义参数绑 ...
随机推荐
- springboot(三):Spring boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Windows下安装Nodejs步骤
最近打算把我们的微信端用Vue.js重构,为什么选择Vue.js,一是之前使用的是传统的asp.net mvc,多页面应用用户体验比单页面要差.二是使用过Angular.js,感觉对开发人员要求较 ...
- [Angularjs]$http.post与$.post
摘要 在angularjs发送post请求的时候,确实很困惑,在传递json数据的时候,总会遇到在服务端无法接受到参数的情况,这里有必要与$.post进行比较学习一下. 一个例子 这里模拟登录的一个场 ...
- TensorFlowSharp入门使用C#编写TensorFlow人工智能应用
TensorFlowSharp入门使用C#编写TensorFlow人工智能应用学习. TensorFlow简单介绍 TensorFlow 是谷歌的第二代机器学习系统,按照谷歌所说,在某些基准测试中,T ...
- 【Spark2.0源码学习】-6.Client启动
Client作为Endpoint的具体实例,下面我们介绍一下Client启动以及OnStart指令后的额外工作 一.脚本概览 下面是一个举例: /opt/jdk1..0_79/bin/jav ...
- 开涛spring3(6.7) - AOP 之 6.7 通知顺序
如果我们有多个通知想要在同一连接点执行,那执行顺序如何确定呢?Spring AOP使用AspectJ的优先级规则来确定通知执行顺序.总共有两种情况:同一切面中通知执行顺序.不同切面中的通知执行顺序. ...
- jQuery选择器中的空格问题
前几天就遇到过这样的问题,明明我用的是('tr :even').css('background','#ccc')想改变表格中行的背景色,反复试了还是没改变.还问了度娘还是没找到原因所在(当时问题描述的 ...
- 【2017-06-01】Linq基础+Lambda表达式实现对数据库的增删改查
一.Linq to sql 类 高集成化的数据库访问技术 使用Linq可以代替之前的Ado.Net.省去了自己敲代码的实体类和数据访问类的大量工作. 实体类: 添加一个Linq to sql 类 -- ...
- 写给Android App开发人员看的Android底层知识(8)
(十)PMS及App安装过程 PMS,全称PackageManagerService,是用来获取Apk包的信息的. 在前面分析四大组件与AMS通信的时候,我们介绍过,AMS总是会使用PMS加载包的信息 ...
- AngularJS语法基础及数据绑定——详解各种数据绑定指令、属性应用
AngularJS简单易学,但是功能强大.特别是在构建单页面应用方面效果显著.而 数据绑定 可以说是他被广泛使用的最主要的优点.他舍弃了对DOM的操作方式,一切都由AngularJS来自动更新视图,我 ...