导入导出功能需求是这样的:按照条件查询出结果,然后将这些结果以excel形式导出;修改字段信息后(主键不允许修改)导入即覆盖原字段信息,完成更新。本例是借助poi完成的,将poi-3.9.jar导入到WEB-INF下的lib的文件夹,与此一起导入的还有commons-io-1.3.2.jar,commons-fileupload-1.2.1.jar,用于io输入和文件上传。
一、导出
功能:选择时间条件——导出——选择保存路径——保存,如下图所示
实现过程:写一个创建excel的方法,先创建一个excel文件,创建好工作表,表头;然后将数据内容填充到里面,数据是根据查询的结果而来;最后保存excel文件至服务器的一个临时位置(每次会覆盖),用户下载的时候从这个位置下载到客户端。
Excel创建代码:
public static void createExcel(List<Sku> list) throws SQLException{
// 创建一个Excel文件
HSSFWorkbook workbook = new HSSFWorkbook();
// 创建一个工作表
HSSFSheet sheet = workbook.createSheet("sku表");
// 添加表头行
HSSFRow hssfRow = sheet.createRow(0);
// 设置单元格格式居中
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 添加表头内容
HSSFCell headCell = hssfRow.createCell(0);
headCell.setCellValue("服务SKU");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(1);
headCell.setCellValue("内外部判别");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(2);
headCell.setCellValue("产品名称");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(3);
headCell.setCellValue("规格型号");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(4);
headCell.setCellValue("发票名称");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(5);
headCell.setCellValue("状态");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(6);
headCell.setCellValue("生命周期");
headCell.setCellStyle(cellStyle);
headCell = hssfRow.createCell(7);
headCell.setCellValue("生成时间");
headCell.setCellStyle(cellStyle);
// 添加数据内容
for (int i = 0; i < list.size(); i++) {
hssfRow = sheet.createRow((int) i + 1);
Sku student = list.get(i);
// 创建单元格,并设置值
HSSFCell cell = hssfRow.createCell(0);
cell.setCellValue(student.getSku());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(1);
cell.setCellValue(student.getNwjduge());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(2);
cell.setCellValue(student.getProname());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(3);
cell.setCellValue(student.getSername());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(4);
cell.setCellValue(student.getInvname());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(5);
cell.setCellValue(student.getState());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(6);
cell.setCellValue(student.getLife());
cell.setCellStyle(cellStyle);
cell = hssfRow.createCell(7);
cell.setCellValue(student.getCreatetime());
cell.setCellStyle(cellStyle);
}
// 保存Excel文件
try {
OutputStream outputStream = new FileOutputStream("/usr/java/tomcat/apache-tomcat-7.0.85/temp/sku.xls");
workbook.write(outputStream);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
下载代码:
<%
SkuDaoImpl sku = new SkuDaoImpl();
List<Sku> skuList = sku.findAll();
FullExcel.createExcel(skuList); //查询的结果,便于插入Excel填充数据
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
//用户下载的保存路径
if (request.getParameter("file") != null) {
OutputStream os = null;
FileInputStream fis = null;
try {
String file = request.getParameter("file");
if (!(new File(file)).exists()) {
System.out.println("没有文件");
return;
}
System.out.println("这个文件名为:"+file);
os = response.getOutputStream();
response.setHeader("content-disposition", "attachment;filename=" + file);
response.setContentType("application/vnd.ms-excel");//此项内容随文件类型而异
byte temp[] = new byte[1000];
fis = new FileInputStream(file);
int n = 0;
while ((n = fis.read(temp)) != -1) {
os.write(temp, 0, n);
}
} catch (Exception e) {
out.print("出错");
} finally {
if (os != null)
os.close();
if (fis != null)
fis.close();
}
out.clear();
out = pageContext.pushBody();
}
%>
<form action="" method="post">
<select name="file">
<option value="/usr/java/tomcat/apache-tomcat-7.0.85/temp/sku.xls"> //从服务器指定位置下载Excel文件
服务SKU码
</option>
</select>
<input type="submit" value="确定">
</form>
二、导入
功能:导入——选择文件——上传,如下图所示
实现过程:用户先上传文件至服务器的临时位置,然后写一个读取excel的方法,程序从服务器的临时位置读取excel文件;然后循环工作表和行,将单元格的内容存入集合;再上传至临时表(每次先清空),再根据sku(主键)更新正式数据库即可完成导入文件更新字段信息。
上传代码,使用了fileupload的jar包:
<%
DiskFileItemFactory diskfactory = new DiskFileItemFactory();//创建工厂类对象
ServletFileUpload fileUpload = new ServletFileUpload(diskfactory);//使用工厂创建解析器对象
try {
List<FileItem> fileItems = fileUpload.parseRequest(request);
for(FileItem item:fileItems) {
if(item.isFormField()) {
System.out.println(new String(item.getString().getBytes("ISO-8859-1"),"utf-8"));
} else{
String fileName = item.getName();
item.write(new File("/usr/java/tomcat/apache-tomcat-7.0.85/temp/sku.xls"));//写入到服务器的临时位置
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
List<Sku> temp=FullExcel.readExcel();//调用读取Excel方法
FullExcel.truncate();//清空临时表
for (Sku s : temp){
FullExcel.addTemp(s);//写入临时表
}
FullExcel.update();//更新正式表的字段信息
%>
Excel读取代码:
public static List<Sku> readExcel() {
List<Sku> list = new ArrayList<Sku>();
HSSFWorkbook workbook = null;
try {
// 读取Excel文件
//String sep = System.getProperty("file.separator");
InputStream inputStream = new FileInputStream("/usr/java/tomcat/apache-tomcat-7.0.85/temp/sku.xls");
workbook = new HSSFWorkbook(inputStream);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
// 循环工作表
for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
HSSFSheet hssfSheet = workbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// 循环行
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow == null) {
continue;
}
// 将单元格中的内容存入集合
Sku sku = new Sku();
HSSFCell cell = hssfRow.getCell(0);
if (cell == null) {
continue;
}
sku.setSku(cell.getStringCellValue());
cell = hssfRow.getCell(1);
if (cell == null) {
continue;
}
sku.setNwjduge(cell.getStringCellValue());
cell = hssfRow.getCell(2);
if (cell == null) {
continue;
}
sku.setProname(cell.getStringCellValue());
cell = hssfRow.getCell(3);
if (cell == null) {
continue;
}
sku.setSername(cell.getStringCellValue());
cell = hssfRow.getCell(4);
if (cell == null) {
continue;
}
sku.setInvname(cell.getStringCellValue());
cell = hssfRow.getCell(5);
if (cell == null) {
continue;
}
sku.setState(cell.getStringCellValue());
cell = hssfRow.getCell(6);
if (cell == null) {
continue;
}
sku.setLife(cell.getStringCellValue());
list.add(sku);
}
}
return list;
}
//上传添加(清空数据库)
public static void truncate() throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
String sql1 = "truncate table TEMP";
try{
conn = DBUtil.getConnection();
ps = conn.prepareStatement(sql1);
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
throw new SQLException("添加数据失败");
}
}
//上传添加(写入临时数据库)
public static void addTemp(Sku s) throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
String sql2="insert into TEMP(sku,nwjudge,proname,sername,invname,state,life)values(?,?,?,?,?,?,?)";
try{
conn = DBUtil.getConnection();
ps = conn.prepareStatement(sql2);
ps.setString(1, s.getSku());
ps.setString(2, s.getNwjduge());
ps.setString(3, s.getProname());
ps.setString(4, s.getSername());
ps.setString(5, s.getInvname());
ps.setString(6, s.getState());
ps.setString(7, s.getLife());
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
throw new SQLException("添加数据失败");
}
}
//根据sku更新数据库(正式数据库)
public static void update() throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
String sql = "update SKU a,TEMP b set a.nwjudge=b.nwjudge,a.proname=b.proname,a.sername=b.sername,a.invname=b.invname,a.state=b.state,a.life=b.life WHERE a.sku=b.sku";
try{
conn = DBUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
throw new SQLException("添加数据失败");
}
}
}
刚开始做导入导出的时候还挺困难的,查阅了很多资料,这个算是比较简单的导入导出了,其中用到了IO知识;其实可以直接从内存中读取excel,我这边做了一个中转的方法,先上传至服务器;至于更新用的临时表,是为了程序性能,批量更新的时候如果数据量大,逐条更新会降低程序性能。此外主要就是利用了第三方包。不足之处还有很多,希望以后越做越好吧~