poi 后台处理table导出成excel 解决跨行跨列的问题

前一阵子遇到一个问题 要将页面上table里面的所有元素导出成excel并且要带样式。 在网上找了下用js可以解决,但是要在ie的安全设置里面设置一个 对未标记为可安全执行脚本的ActiveX空间初始化并执行脚本启用。 感觉不太好用于是就自己写了个前台传值到后台通过poi导出成excel的方法 代码有很多不足的地方请大家见谅,并指出来共同探讨。废话不说了 直接上代码


要导出的表格
[img]http://dl.iteye.com/upload/attachment/351245/1765d303-cdfe-31bb-b67d-18e8e6ff5bfd.png[/img]

导出后的结果
[img]http://dl.iteye.com/upload/attachment/351250/b73a24f8-b695-3760-bad9-18b2af895e4f.png[/img]


代码
1.先在页面上弄个隐藏域id叫dataInfo,通过js把数据传到后台
2.把页面上的值以固定的格式传到后台


[b]---jsp页面[/b]
/js把需要的值传给后台
function gettitle(tab){
var doc=document.getElementById(tab);
var rows=doc.rows.length; //表格的总行数
var dataInfo=""; //传入后台的数据
var maxcol=0; //最大的列数
for(var r=0;r<rows;r++){
var colspan=1;//单元格所占单元格数
var rowspan=1;//单元格所跨的行数
var current=1;//td当前打印位置
var maxcolumn=doc.rows[r].cells.length;//当前行列数
<%--
存入的格式 0,0,1,1,值★0,1,1,2,值★0,2,1,1,值
1,0,1,1,值★1,1,1,1,null★1,2,1,1,值
*第一个参数是当前行,第二个参数是当前列,第三个参数是当前行所跨的行,第四个参数是当前行所跨的列,第五个参数是当前单元格的值
--%>
for(c=0;c<maxcolumn;c++){
if(maxcol<maxcolumn)
{
maxcol=maxcolumn;
}
}

var temp=0;
for(var i=0;i<maxcol;i++)
{
//var rowscount=0;//td当前所跨的行数
if(doc.rows[r].cells[i]!=null)
{
var color=doc.rows[r].cells[i].currentStyle.color;
colspan=doc.rows[r].cells[i].colSpan; //取的当前单元格所占单元格列数
rowspan=doc.rows[r].cells[i].rowSpan; //取得当前单元格所占单元格行数
dataInfo=dataInfo+r+","+i+","+rowspan+","+colspan+","+doc.rows[r].cells[i].innerText+","+color+"★";
}
}
}
document.getElementById("dataInfo").value=dataInfo;
document.forms[0].submit();
}


//导出的table元素
<table align="center" border="1" id="tab" style="font-size: 20px;width: 50px;height: 30px">
<tr>
<td width="30px" colspan="2" align="center" style="color:yellow;" >小强</td>
<td width="30px" rowspan="3" align="center" style="color:#00ff00;" ><center>a</center></td>
<td width="30px" rowspan="2" style="color:#3366ff">xxx</td>
<td width="30px" rowspan="2" style="color:#123432">www</td>
</tr>
<tr>
<td width="30px" colspan="2"><center>b</center></td>
</tr>
<tr>
<td align="center" width="30px">c</td>
<td align="center" width="30px">d</td>
<td align="center" width="30px" style="color: #ff33ff" colspan="2">e</td>
</tr>
</table>

//按钮的单击事件
<input type="button" οnclick="gettitle('tab')" value="传值后台处理法">


[b]--------后台action [/b]
public String poiExcel() {
// 获得页面table元素里面的数据
// 存入的格式 0,0,1,1,值★0,1,1,2,值★0,2,1,1,值
// 1,0,1,1,值★1,1,1,1,null★1,2,1,1,值
// *第一个参数是当前行,第二个参数是当前列,第三个参数是当前行所跨的行,第四个参数是当前行所跨的列,第五个参数是当前单元格的值
String dataInfo = request.getParameter("dataInfo");


//去掉最后1个★
if (dataInfo != null && !"".equals(dataInfo)) {
String lastString = dataInfo.substring(dataInfo.length() - 1,
dataInfo.length());
if ("★".equals(lastString)) {
dataInfo = dataInfo.substring(0, dataInfo.length() - 1);
}
}

//通过★号分割,获得每个td里面的详细信息
String[] list = dataInfo.split("★");



//创建hssfWorkbook工作簿
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
HSSFSheet hssfSheet = hssfworkbook.createSheet("one");
hssfSheet.setZoom(100, 100);

// 为hssfworkbook创建不同的单元格样式
// HSSFCellStyle cellStyle = setStyle(hssfworkbook);
// HSSFCellStyle cellstyle1 = setStyle1(hssfworkbook);
// 字体颜色为红色
// HSSFFont font = hssfworkbook.createFont();
// font.setColor(HSSFFont.COLOR_RED);


// 求最大行与最大列
int col = 0;
int temp = 55; //零时变量只是为了比较好判断读到几行了
int tempMaxCell = 0; //table中的最大列数

int maxCell = 0; // 最大列数
int maxRow = 0; // 总共的行数


//求出总行数与最大的列数
for (int i = 0; i < list.length; i++) {
String zhi = list[i];
String[] value = zhi.split(",");
int rowNumber = Integer.parseInt(value[0]); //当前所处列的编号
int colspan = Integer.parseInt(value[3]); //跨的列数

if (rowNumber != temp) {
maxRow++;
temp = rowNumber;
if (maxCell < tempMaxCell) {
maxCell = tempMaxCell;
}
tempMaxCell = 0;
}
tempMaxCell += colspan;
}



//值数据的封装
String[][] database = new String[maxRow][maxCell];
//颜色数据的封装
String[][] colors = new String[maxRow][maxCell];

Integer[][] rowsInfo = new Integer[maxRow][maxCell];

int countNum = 0;



//
for (int i = 0; i < list.length; i++) {
String zhi = list[i];
String[] value = zhi.split(",");
int rowNumber = Integer.parseInt(value[0]); //行编号
int colNumber = Integer.parseInt(value[1]); //列编号
int rowspan = Integer.parseInt(value[2]); //所跨的行数
int colspan = Integer.parseInt(value[3]); //所跨的列数

if (rowNumber != temp) {
temp = rowNumber;
col = 0;
countNum = 0;
}
// 合并单元格 第一个参数是开始的行编号,第二个参数是结束的行编号,第三个是开始的列编号,第四个参数是结束的列编号

//既跨行也跨列的合并方法
if (rowspan != 1 && colspan != 1) {
hssfSheet.addMergedRegion(new CellRangeAddress(rowNumber,
rowNumber + rowspan - 1, colNumber, colNumber + colspan
- 1));
for (int j = 0; j < rowspan; j++) {
for (int k = 0; k < colspan; k++) {
rowsInfo[rowNumber + j][col + k] = 1111;
}
}
rowsInfo[rowNumber][col] = null;
//只跨行的单元格合并方法
} else if (rowspan != 1) {
hssfSheet.addMergedRegion(new CellRangeAddress(rowNumber,
rowNumber + rowspan - 1, col, col));
for (int j = 1; j < rowspan; j++) {
rowsInfo[rowNumber + j][col] = 1111;

}
//只跨列的单元格合并方法
} else if (colspan != 1) {
if (rowsInfo[rowNumber][col] != null
&& rowsInfo[rowNumber][col] == 1111) {
hssfSheet.addMergedRegion(new CellRangeAddress(rowNumber,
rowNumber, col + 1, col + colspan));
rowsInfo[rowNumber][colNumber + colspan] = 2222;
} else {
hssfSheet.addMergedRegion(new CellRangeAddress(rowNumber,
rowNumber, col, col + colspan - 1));
rowsInfo[rowNumber][colNumber + colspan - 1] = 2222;
}
}

//值数据的存储
database[rowNumber][countNum] = zhi.substring(8,zhi
.lastIndexOf(","));
//颜色数据的存储
colors[rowNumber][countNum] = zhi.substring(
zhi.lastIndexOf(",") + 1, zhi.length());
col = col + colspan;// 将当前位置往后移动colspan数量
countNum++;
}




// 自定义颜色索引 颜色这块还有点问题
short colorIndex = 8;
// 单元格里面设置
for (int i = 0; i < maxRow; i++) {
HSSFRow hssfRow = hssfSheet.createRow(i);
int count = 0;
for (int j = 0; j < maxCell; j++) {
if (rowsInfo[i][j] == null) {
HSSFCellStyle cell = hssfworkbook.createCellStyle();
// 设置单元格样式内的字体
HSSFFont hssfFont = hssfworkbook.createFont();
// 设置字体大小
hssfFont.setFontHeightInPoints((short) 11);
String str = colors[i][count];
// String str = "#3366FF";
int[] color = new int[3];
if (str.length() == 7) {
color[0] = Integer.parseInt(str.substring(1, 3), 16);
color[1] = Integer.parseInt(str.substring(3, 5), 16);
color[2] = Integer.parseInt(str.substring(5, 7), 16);

HSSFPalette palette = hssfworkbook.getCustomPalette();
palette.setColorAtIndex(colorIndex, (byte) color[0],
(byte) color[1], (byte) color[2]);
// 设置字体颜色
hssfFont.setColor(colorIndex);
colorIndex++;
//页面上传的是字符red ,black等颜色的处理 还有好多省略了
} else if (str.equals("red")) {
// 设置字体颜色
hssfFont.setColor(HSSFColor.RED.index);
} else if (str.equals("black")) {
hssfFont.setColor(HSSFColor.BLACK.index);
} else if (str.equals("yellow")) {
hssfFont.setColor(HSSFColor.YELLOW.index);
}
cell.setFont(hssfFont);
this.setCellStyle(cell, hssfRow.createCell(j),
database[i][count]);
count++;
}
}
}
//保存成xls文件
try {
FileOutputStream fileoutputstream = new FileOutputStream(
"D:/exceltext.xls");
hssfworkbook.write(fileoutputstream);
fileoutputstream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值