当前主流的后台管理系统,相信都会有文档导入导出的功能。而这其中用到的技术又是多种多样,有用POI框架,也有用JXLS技术的。技术只是手段,项目中实现功能最重要。今天主要说下如何利用POI技术操作EXCEL文档。
=================================================================
POI 操作EXCEL文档导入导出,大致有两种方式:
1. 用户模式(usermodel):一次性将xls文件读入到内存,创建dom结构处理
2. 事件模式(eventusermodel):以流的形式读取xls文件,读取xls文件占用相对较小的内存
-----------------------------------------------------------------------------------------------------------
第一种方式容易造成内存溢出的异常,第二种的话是逐条读取数据,即使文档中有千万条数据,也依然可以正常读取,不会造成内存溢出。今天使用的就是第二中方式,基于事件模式的excel文档导入。具体的两种模式的区别,大家可以网上百度下,了解了这两种模式之后,对于大数据EXCEL导入的优化会有很好的帮助。(参考:http://blog.csdn.net/lipinganq/article/details/77678443 )
**********************************************************************
POI 导入EXCEL文档:(设计思路)
1,首先,要导入EXCEL 文档,就必须要先有导入的模板文件,在这里,我提供好了制作好的EXCEL 模板文件提供下载;(EXCEL文档模板示例下载 )
2,有了EXCEL 模板文件,就开始编写页面,并编写后台逻辑代码了;
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 14-6-26
Time: 下午3:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="/aml/includes/amlincludes.jsp" %>
~
~
$("#"+"${param.perfix}table").stk_query();
${param.perfix}showUpdateWindow(data)
${param.perfix}showAddQDIIListWindow();
${param.perfix}remove();
${param.perfix}exportAll("csv");
${param.perfix}exportAll("xls");
下载模板
${param.perfix}importAmlRiskList()
$("#"+"${param.perfix}importWindow").stk_hide()
客户名称
证件类型
<%-- <%– –%>--%>
证件号码
客户ID
备注
<%-- --%>
if ($("#"+"${param.perfix}editForm").stk_checkForm()) {
${param.perfix}save();
}
$("#"+"${param.perfix}editWindow").stk_hide()
<%--
--%>
后台的ACTION :
package com.sinitek.sirm.web.amlqd;
import com.sinitek.sirm.busin.aml.service.AmlServiceFactory;
import com.sinitek.sirm.busin.aml.service.impl.AmlQDIIListServiceImpl;
import com.sinitek.sirm.busin.aml.utils.*;
import com.sinitek.sirm.common.utils.StringUtil;
import com.sinitek.sirm.common.web.RequestContext;
import com.sinitek.sirm.common.web.tag.PageLoadContext;
import com.sinitek.sirm.framework.utils.io.Uploader;
import com.sinitek.sirm.framework.utils.io.UploaderFile;
import com.sinitek.sirm.framework.utils.io.UploaderFileList;
import com.sinitek.spirit.webcontrol.table.ICheckBoxPluginAware;
import com.sinitek.spirit.webcontrol.table.ITableAware;
import org.directwebremoting.io.FileTransfer;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by user on 2016/4/21.
*/
public class AmlQDIIRCAction implements ITableAware,ICheckBoxPluginAware {
public static final String TYPE_RC = "rc";
public static final String TYPE_DQ = "dq";
public static void loadpage(PageLoadContext context) {
context.getPageContext().setAttribute("cttpList", AmlServiceFactory.getAmlOptionsService().getOptionMap(OptionsUtils.citpList));
}
@Override
public Object callCheckBoxPlugin(List
/*
* Created on 2005-3-14
*/
package com.sinitek.sirm.busin.aml.utils;
/**
* @author ray.huang
*/
import com.sinitek.sirm.common.utils.IOUtil;
import com.sinitek.sirm.common.web.RequestContext;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.*;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;
public class ExcelUtil {
public static final int pageNum = 10000000;//每个worksheet显示的数据条数
public static String writeExcel(String excelPath,String reportName,List colName,List data,List datap,String tableName){
//打开文件
String fileName = "";
String excelName = "";
try{
//String excelPath = ExcelConfig.getInstance().excelFile;
//String excelPath = Config.getConfig("excel");
//FinderManager fm = new FinderManager();
excelName =reportName+".xls";
fileName = excelPath+System.getProperty("file.separator")+excelName;
createFile(fileName);
WritableWorkbook book = Workbook.createWorkbook(new File(fileName));
//计算列数
int j = 1;
int k = 2;
int sheetNum = 0;
WritableSheet sheet = book.createSheet("第1页",sheetNum);
int colNameLen = colName.size();
int middle = (colNameLen/2)-1;
//打印标题
Label label=new Label(middle,0,tableName);
sheet.addCell(label);
//打印头
WritableFont wf = new WritableFont(WritableFont.ARIAL,10, WritableFont.NO_BOLD,false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);// 设置写入字体
WritableCellFormat wcfF = new WritableCellFormat(wf);// 设置CellFormat
wcfF.setBackground(Colour.GRAY_25);
for(int i=0;i
具体的保存到数据库中的方法就不详细写了,大体上的方法就是这样,大家可以试一试。当然了,由于各个机构公司使用的框架不同,后台业务逻辑不同,导致方法可能会有所小的改动,但是本质的方法都是一样的。例子中的框架是自己机构独有的,因此大家在测试的时候,不可照搬照照挪,要注意稍微改动下,本例只是一个启发的作用,希望能有更好的方法,欢迎留言讨论哦!
==================================================
后续:
对于EXCEL导出,可能对于很多新手刚入行的程序员还是一个有点难度的问题。
所以在这里的话,我也做了一个小的DEMO给大家,希望对于新人能够有所帮助和学习。这个小的DEMO在导入速度和性能上也都还好,EXCEL单个sheet中最多支持的20000条数据,我做了下测试,只需要1分12秒的时候解析完成,还是很快的。当然了,对于大神来说,这可能不算什么,也许代码还能继续优化,希望看过DEMO的网友能够继续优化,也欢迎大家更多和我分享和交流。(DEMO下载地址: http://download.csdn.net/download/samile6899/10171204 )