您的位置:首页 > 其它

POI根据XML模版读取Excel

2015-11-02 20:52 330 查看
 
      实际开发中,总会有一些让人想象不到的需求。最近一个月都在开发这样一个需求,用户只需要excel指定单元格的数据,其他数据不做保留。至于用户用什么样的情况下才用这些数据,不是很明白(组长说你先开发出来再说,最后需要结合到别人开发的功能中去)。就这样,我就和阿瑾着手开发开发。

主要思路:

       设置XML模版(指定单元格)

       读取XML设置的单元格信息

       POI解析指定单元格数据

       将数据存入数据库

     


       选择指定模版,然后点击上传,数据直接存入数据库中

一、XML模版

   要求:

         1、可以灵活的读取指定的sheet页

         2、可以随意设置想要获取的单元格信息

         
<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<Excel>
<sheet>
<column sheet="0">
<name>column1</name>
<value>14,6</value>
</column>
<column sheet="0">
<name>column2</name>
<value>15,7</value>
</column>
</sheet>
<sheet>
<column sheet="1">
<name>column3</name>
<value>28,6</value>
</column>
<column sheet="1">
<name>column4</name>
<value>34,11</value>
</column>
</sheet>
<sheet>
<column sheet="2">
<name>column5</name>
<value>8,3</value>
</column>
<column sheet="2">
<name>column6</name>
<value>12,5</value>
</column>
</sheet>
<sheet>
<column sheet="3">
<name>column7</name>
<value>8,7</value>
</column>
<column sheet="3">
<name>column8</name>
<value>11,8</value>
</column>
</sheet>
</Excel></span>

二、Service

   注:将单元格数据保存在库中

<span style="font-size:18px;">public class ExcelUploadDaoImpl extends HibernateDaoSupport implements ExcelUploadDao {
@Override
public int saveExcel(String content,String tableName) {

String column="";
//根据conten中有多少类生成相应的列数
String[] columnNames=content.split(",");

for(int i=1;i<=columnNames.length;i++){
if(i==columnNames.length){
column+="column"+i;
}else{
column+="column"+i+",";
}
}

String sqlString="insert into "+tableName+"("+column+")values("+content+");";

int i= getSession().createSQLQuery(sqlString).executeUpdate();
System.out.println(i);

return i;
}
}</span>

三、action

<span style="font-size:14px;">package cn.itcast.s2sh.struts2.action;

import java.io.File;
import java.io.FileInputStream;
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.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.aspectj.util.FileUtil;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import cn.itcast.s2sh.struts2.service.ExcelUploadService;
import com.opensymphony.xwork2.ActionSupport;

public class ExcelUploadAction extends ActionSupport {

private ExcelUploadService excelUploadService;

public ExcelUploadService getExcelUploadService() {
return excelUploadService;
}

public void setExcelUploadService(ExcelUploadService excelUploadService) {
this.excelUploadService = excelUploadService;
}

public String check() {
return "check";
}

// myFile属性用来封装上传的文件
private File myFile;

// myFileContentType属性用来封装上传文件的类型
private String myFileContentType;

// myFileFileName属性用来封装上传文件的文件名
private String myFileFileName;

//定义表名
private String tableName;

//返回回传信息
private String msgString;

/**
*选择自己的模版
*   0是推进表
*   1是日记录表
*  2是日记录
*/
private int myTemplate;

public int getMyTemplate() {
return myTemplate;
}

public void setMyTemplate(int myTemplate) {
this.myTemplate = myTemplate;
}

/**
* 上传文件
* @return
* @throws Exception
*/
public void add() throws Exception {
HttpServletResponse response=ServletActionContext.getResponse();
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");

try {
// ================================1、将上传的excel保存在服务器上一份========================
// 设置服务器的上传文件目录
String uploadPath = ServletActionContext.getServletContext()
.getRealPath("/upload");

// 写到指定路径
File fileExcel = new File(uploadPath);

// 如果指定路径不存在就创建
if (!fileExcel.exists()) {
fileExcel.mkdir();
}

//会将文件上传到upload外面
if (myFile != null) {
File out = new File(uploadPath + myFileFileName);
myFile.renameTo(out);
}

//基于myFile创建一个文件输入流
InputStream is = new FileInputStream(myFile);

//设置上传文件名称
Date nowDate=new Date();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddHHmmss");

String date="";
date=dateFormat.format(nowDate);
String fileNameString=date+this.getMyFileFileName();

//将上传文件复制到服务器指定位置
File toFile = new File(uploadPath,fileNameString);
FileUtils.copyFile(myFile,toFile);

// 创建一个输出流
OutputStream os = new FileOutputStream(toFile);

// ================================2、读取xml配置文件========================

// 读取XML文件
SAXReader reader = new SAXReader();

// 设置模版路径
String rootPath = ServletActionContext.getServletContext()
.getRealPath("/");
String config ="";

if(0==myTemplate){
tableName="advancetable";
config = rootPath + "WEB-INF\\jsp\\advanceTemplate.xml";
}else if(1==myTemplate){
tableName="dayrecordtable";
config = rootPath + "WEB-INF\\jsp\\dayRecordTableTemplate.xml";
}else{
tableName="dayrecord";
config=rootPath+"WEB-INF\\jsp\\dayRecordTemplate.xml";
}

File file = new File(config);

//读取服务器上的模版
Document document = reader.read(file);
Element root = document.getRootElement();

List<String> contentList = new ArrayList<String>();
String value = null;
String nameString = null;
String valueString = null;
String sheetString = null;

// 读取sheet节点
List<Element> nodes = root.elements("sheet");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// 读取column节点
List<Element> elmChild = elm.elements("column");
//遍历column节点下的内容
for (Iterator childIterator = elmChild.iterator(); childIterator
.hasNext();) {
Element element = (Element) childIterator.next();

//column节点属性为sheet
Attribute attribute = element.attribute("sheet");
//column节点下的子节点
Element nameElement = element.element("name");
Element valueElement = element.element("value");

//获取column下的节点信息
nameString = nameElement.getText();
valueString = valueElement.getText();
sheetString = attribute.getText();

value = sheetString + "," + nameString + "," + valueString;

//将页名、字段列名、单元格行与列信息存储
contentList.add(value);
}
}

// ==============================3、根据配置文件设置的模版获取Excel单元格的数据(2003和2007版)============================
//获取后缀名.xls-2003  .xlsx-2007
String fileName=myFileFileName.substring(myFileFileName.lastIndexOf(".")+1,myFileFileName.length());

int row = 0;
int column = 0;
String cellContentString="";

//如果上传文件为2003Excel和WPS
if("xls".equals(fileName) ||"et".equals(fileName)){
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream(
myFile));

for (int i = 0; i < contentList.size(); i++) {
//获取单元格的行列信息
String valueLiString = contentList.get(i);
List<String> list = new ArrayList<String>();
StringTokenizer stringTokenizer = new StringTokenizer(
valueLiString, ",");

while (stringTokenizer.hasMoreTokens()) {
list.add(stringTokenizer.nextToken());
}

//获取页的信息
int sheetIndex = Integer.parseInt(list.get(0));
HSSFSheet sheet = hssfWorkbook.getSheetAt(sheetIndex);

//获取行与列的信息
row = Integer.parseInt(list.get(list.size() - 2));
column = Integer.parseInt(list.get(list.size() - 1));

//POI根据行与列获取单元格数据
HSSFRow rowValue = sheet.getRow(row);
HSSFCell cellValue = rowValue.getCell((short) column);

String cellContent = getStringCellValue(cellValue);

//拼接获得的单元格数据
if(i==contentList.size()-1){
cellContentString+=cellContent;
}else{
cellContentString=cellContentString+cellContent+",";
}
}
}else{	//上传文件为excel-2007
XSSFWorkbook hssfWorkbook = new XSSFWorkbook(new FileInputStream(
myFile));

for (int i = 0; i < contentList.size(); i++) {
//获取单元格的行列信息
String valueLiString = contentList.get(i);
List<String> list = new ArrayList<String>();
StringTokenizer stringTokenizer = new StringTokenizer(
valueLiString, ",");
while (stringTokenizer.hasMoreTokens()) {
list.add(stringTokenizer.nextToken());
}

//获取页的信息
int sheetIndex = Integer.parseInt(list.get(0));
XSSFSheet sheet = hssfWorkbook.getSheetAt(sheetIndex);

//获取行与列的信息
row = Integer.parseInt(list.get(list.size() - 2));
column = Integer.parseInt(list.get(list.size() - 1));

//POI根据行与列获取单元格数据
XSSFRow rowValue = sheet.getRow(row);
XSSFCell cellValue = rowValue.getCell((short) column);

String cellContent = getStringCellValuexlxs(cellValue);

//拼接获得的单元格数据
if(i==contentList.size()-1){
cellContentString+=cellContent;
}else{
cellContentString=cellContentString+cellContent+",";
}
}
}

is.close();
os.close();

// ==============================4、将单元格数据写入到数据库============================
int result=excelUploadService.saveExcel(cellContentString,tableName);

//判断是否成功
if(result==0){
renderText("fail");
}else{
renderText("success");
}

} catch (DocumentException e) {
e.printStackTrace();
}
}

/**
* 直接输出文本,默认编码为UTF-8.
*/
protected void renderText(final String text) {
render(text, "text/plain;charset=UTF-8");
}

protected void render(final String text, final String contentType) {
try {
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType(contentType);
response.getWriter().write(text);
} catch (IOException e) {
System.out.println("出错了");
}
}
/**
* 获取单元格数据内容为字符串类型的数据
*
* @param cell
*            Excel单元格
* @return String 单元格数据内容
*/
private String getStringCellValue(HSSFCell cell) {
String strCell = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
strCell = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
strCell = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
strCell = "";
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
if (cell == null) {
return "";
}
return strCell;
}

/**
* 获取单元格数据内容为字符串类型的数据
*
* @param cell
*            Excel单元格
* @return String 单元格数据内容
*/
private String getStringCellValuexlxs(XSSFCell cell) {
String strCell = "";
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING:
strCell = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
strCell = String.valueOf(cell.getNumericCellValue());
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_BLANK:
strCell = "";
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
if (cell == null) {
return "";
}
return strCell;
}

public File getMyFile() {
return myFile;
}

public void setMyFile(File myFile) {
this.myFile = myFile;
}

public String getMyFileContentType() {
return myFileContentType;
}

public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}

public String getMyFileFileName() {
return myFileFileName;
}

public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}

public String getMsgString() {
return msgString;
}

public void setMsgString(String msgString) {
this.msgString = msgString;
}

}</span>

四、Jsp

<span style="font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!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">
<script type="text/javascript"
src="${pageContext.request.contextPath}/jquery/jquery-2.1.1.js"></script>
<script type="text/javascript"
src="${pageContext.request.contextPath}/jquery/jquery-form.js"></script>
<script type="text/javascript"
src="${pageContext.request.contextPath}/jquery/jquery-2.1.1.min.js"></script>
</head>
<body>
<form name="frmfile" id="frmfile" enctype="multipart/form-data"
action="excelUpload_add.action" method="post">
<input type="hidden" name="result" value="">
<div style="margin: 0px 40px; width: 550px;">
<div>
<label>选择模版:</label>
<s:select name="myTemplate" list="#{0:'推进表',1:'日报表',2:'日报'}">
</s:select>
</div>
<fieldset style="margin: 0px auto; width: 500px;">
<legend>上传文件</legend>
<table border="0" cellpadding="0" cellspacing="0"
style="width: 100%;">
<tr>
<td valign="bottom"><input type="file" id="files"
name="myFile" class="files"> <input type="hidden"
name="fileNames" value=""> <input id="buttionUpload"
name="buttionUpload" value="上传" type="button"
style="float: right; _padding: 2px 4px;" onClick="doUpload()" /></br>
<label id="showInfo" name="showInfo"><font color="red"></font>
</label>
</td>
</tr>
</table>
</fieldset>
</div>
<!-- <iframe name='hidden_frame' id="hidden_frame" style='display: none'></iframe> -->
</form>
</body>
</html>
<script type="text/javascript">
function doUpload() {
document.getElementById("showInfo").style.color="red";
document.getElementById("showInfo").innerHTML="正在上传!!!!";

//调用后台,将excel传到action
$('#frmfile').ajaxSubmit(
function(msg) {
if (msg == "success") {
submitFlag = false;
submitFlag2 = false;
document.getElementById("showInfo").innerHTML="成功上传文件!!";
}else{
document.getElementById("showInfo").innerHTML="上传文件失败,请联系管理员!!";
}
});
}
</script></span>

   注:使用$ajax无法实现对上传文件的回调,建议使用ajaxSubmint或者ajaxFrom,两种都可以实现

总结:

        虽然这个Demo比较粗糙,但是核心功能都已经开发完了,POI根据解析的XML读取Excel。开发前组长说了一下这个需求,但是实际应用中没有清晰的告诉我们,导致后面继续开发时,出现很多不合理的地方。比如说,用户不是取几个单元的数据,而是好几十个,到现在的200来个。更无奈的是,用户还想再加几百个单元格,当时我就果断回绝了,这种思路根本不适合取大量的单元格数据。一是取的时候太浪费人力物力;二是,存入数据库也会出现混乱。做什么事情的时候还是要好好考虑这个东西是不是合理,是否具有可行性,否则后果不堪设想。

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: