java code
package com.td.store.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFFont;
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.hssf.util.HSSFColor.HSSFColorPredefined;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType;
public class ExcelUtil {
public static void main(String[] ager){
createTemplate("shangping.xml");
}
//定制生成用户模板信息
/**
* path 是模板信息 XML文件的路径 模板信息统一存放在项目下template文件夹下 传文件名称即可
*
* **/
public static void createTemplate(String path){
//获取模板配置信息的XML文件路径
String realPath = System.getProperty("user.dir")+"/template/"+path;
File file = new File(realPath);
//用jdom解析XML模板配置文件
SAXBuilder builder = new SAXBuilder();
try {
//解析XML文件
Document parse = builder.build(file);
//创建工作薄
HSSFWorkbook wb = new HSSFWorkbook();
//创建sheet工作表 参数给工作表起个名
HSSFSheet sheet = wb.createSheet("sheet0");
//获取XML文件根节点 (excel节点)
Element rootElement = parse.getRootElement();
//获取模板名称
String templateName = rootElement.getAttribute("name").getValue();
//变量行号
int rownum = 0;
//变量列号
int j = 0;
//获取colgroup节点对象
Element colgroup = rootElement.getChild("colgroup");
//设置列宽
setColumnWidth(sheet,colgroup);
//设置标题
//获取标题节点
Element title = rootElement.getChild("title");
//获取标题内的tr节点list
List<Element> trs = title.getChildren("tr");
//循环trs节点
for (int i = 0; i < trs.size(); i++) {
//获取单个tr节点对象
Element tr = trs.get(i);
//获取tr里面的tds对象 (也可能是个集合)
List<Element> tds = tr.getChildren("td");
//创建sheet里面的一行
HSSFRow row = sheet.createRow(rownum);
//创建单元格格式
CellStyle cStyle = wb.createCellStyle();
//循环每一个td
for (j = 0; j < tds.size(); j++) {
//获取td
Element td = tds.get(j);
//创建单元格对象
HSSFCell cell = row.createCell(j);
//获取td里面的属性对象
Attribute rowspan = td.getAttribute("rowspan");
Attribute colspan = td.getAttribute("colspan");
Attribute value = td.getAttribute("value");
//获取value属性的值
String val = value.getValue();
//给cell设置值
cell.setCellValue(val);
//Excel单元格列计数从0开始 需要转换下
int rspan = rowspan.getIntValue()-1;
int cspan = colspan.getIntValue()-1;
//设置字体
HSSFFont font = wb.createFont();
font.setFontName("仿宋_GB2312");
font.setFontHeightInPoints((short)12);
cStyle.setFont(font);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(rspan, rspan, 0, cspan));
}
rownum++;
}
//设置表头信息
//获取表头对象
Element theah = rootElement.getChild("thead");
trs = theah.getChildren("tr");
for (int i = 0; i < trs.size(); i++) {
Element tr = trs.get(i);
HSSFRow row = sheet.createRow(rownum);
List<Element> ths = tr.getChildren("th");
for (j=0; j < ths.size(); j++) {
Element th = ths.get(j);
Attribute valueAttr = th.getAttribute("value");
HSSFCell cell = row.createCell(j);
String value = valueAttr.getValue();
cell.setCellValue(value);
}
rownum++;
}
//设置数据区域样式
Element tbody = rootElement.getChild("tbody");
Element tr = tbody.getChild("tr");
//获取配置文件中,需要设置样式的行数
int repeat = tr.getAttribute("repeat").getIntValue();
//获取tr下面的td 每一列对应的属性
List<Element> tds = tr.getChildren("td");
for (int i = 0; i < repeat; i++) {
//创建行对象
HSSFRow row = sheet.createRow(rownum);
for(j=0;j<tds.size();j++){
Element td = tds.get(j);
HSSFCell cell = row.createCell(j);
setType(wb,cell,td);
}
rownum++;
}
File tempFile = new File("E:\\"+templateName+".xls");
OutputStream stream = new FileOutputStream(tempFile);
wb.write(stream);
//关闭流
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//设置单元格样式
private static void setType(HSSFWorkbook wb, HSSFCell cell, Element td) {
//获取XML TD对象的type属性
Attribute typeAttr = td.getAttribute("type");
//获取type属性值,代表数据类型
String type = typeAttr.getValue();
//单元格样式
HSSFDataFormat format = wb.createDataFormat();
HSSFCellStyle cellStyle = wb.createCellStyle();
//判断节点类型属性
if("string".equals(type)){
//设置默认值
cell.setCellValue("");
cell.setCellType(CellType.STRING);
}else if("double".equals(type)){
cell.setCellType(CellType.NUMERIC);
}else if("int".equals(type)){
cell.setCellValue(0);
cell.setCellType(CellType.NUMERIC);
}else if("enum".equals(type)){
CellRangeAddressList regions =
new CellRangeAddressList(cell.getRowIndex(), cell.getRowIndex(),
cell.getColumnIndex(), cell.getColumnIndex());
Attribute enumAttr = td.getAttribute("format");
String enumValue = enumAttr.getValue();
DVConstraint constraint =
DVConstraint.createExplicitListConstraint(enumValue.split(","));
HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
wb.getSheetAt(0).addValidationData(dataValidation);
}
cell.setCellStyle(cellStyle);
}
//设置列宽的方法
private static void setColumnWidth(HSSFSheet sheet,Element colgroup){
List<Element> cols = colgroup.getChildren("col");
for (int i = 0; i < cols.size(); i++) {
Element col = cols.get(i);
Attribute width = col.getAttribute("width");
//获取到配置的宽度,截取计量单位 是em或者px
String unit = width.getValue().replaceAll("[0-9,\\.]", "");
//获取到配置的宽度,截取设置值
String value = width.getValue().replaceAll(unit, "");
int v = 0;
//判断单位为空 或者为em 这里我不用String的isEmpty判断空是因为如果String是null,会报空指针异常,但是我不知道什么问题,StringUtils在lang包下面没找到,先用String的isEmpty方法
//同时计量单位为px时进入方法
if(unit.isEmpty()||"px".equals(unit)){
//poi宽度转换为excel宽度
v = Math.round(Float.parseFloat(value)*37F);
}else if("em".equals(unit)){
v = Math.round(Float.parseFloat(value)*267.5F);
}
//设置进去值
sheet.setColumnWidth(i, v);
}
}
}
XML template
<?xml version="1.0" encoding="UTF-8"?>
<excel id="shangping" code="shangping" name="商品信息模板">
<!-- 列宽信息设置 -->
<colgroup>
<col index="A" width="20em"></col>
<col index="B" width="20em"></col>
<col index="C" width="20em"></col>
<col index="D" width="20em"></col>
<col index="E" width="20em"></col>
<col index="F" width="20em"></col>
<col index="G" width="20em"></col>
</colgroup>
<!-- 表头标题信息设置 -->
<title>
<tr heigth="16px">
<td rowspan="1" colspan="7" value="商品信息导入"></td>
</tr>
</title>
<!-- 表头单元格每列名称 -->
<thead>
<tr height="16px">
<th value="商品名" />
<th value="市场价" />
<th value="售价" />
<th value="数量" />
<th value="分类" />
<th value="商品简述" />
<th value="图片路径"></th>
</tr>
</thead>
<!-- 每列输入信息指定类型 repeat属性代表多少行需要遵循设置的样式-->
<tbody>
<tr height="16px" repeat="30">
<td type="string" maxlength="40" /><!--商品名称 -->
<td type="double" /><!--市场价 -->
<td type="double" /><!--售价 -->
<td type="int" /><!--数量 -->
<td type="enum" format="1,2,3,4,5,6,7,8,9,10" /><!--分类 -->
<td type="string" maxlength="100" /><!--商品简述 -->
<td type="string" maxlength="100" /><!--图片全名 -->
</tr>
</tbody>
</excel>