poi uses jdom to parse the xml file to customize the Excel template

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>

Guess you like

Origin blog.csdn.net/qq_36551486/article/details/82917588