ReportUtils.java 12 KB
package com.bsth.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;

import com.bsth.entity.Line;
import com.bsth.entity.realcontrol.ScheduleRealInfo;

public class ReportUtils {
	// private final String packaegName = "com.bsth.entity.";
	private final String packaegName = "com.bsth.entity.realcontrol.";

	/**
	 * /**
	 * 
	 * @param list
	 *            模板中,需要重复显示的行所需的数据
	 * @param map
	 *            模板中除以上list外所有的数据
	 * @param index
	 *            需要重复的行号,该值为行号减1
	 * @param sourcePath
	 *            模板路径
	 * @param targetPath
	 *            生成路径
	 */
	public void excelReplace(List<Iterator<?>> list, Object[] tArray,
			String sourcePath, String targetPath) {
		try {
			// 把源文件放入流中
			POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(
					sourcePath));
			HSSFWorkbook wb = new HSSFWorkbook(fs);
			HSSFSheet sheet = wb.getSheetAt(0);
			HSSFRow row;
			HSSFCell cell = null;
			String key;
			// 取得总行数
			int rowNum = sheet.getLastRowNum();
			// 取得总列数
			int cellNum = sheet.getRow(0).getLastCellNum();

			// 遍历行
			for (int i = 0; i < rowNum; i++) {
				row = sheet.getRow(i);
				// 遍历列
				for (int j = 0; j < cellNum; j++) {
					if (row == null) {
						continue;
					}
					cell = row.getCell(j);
					if (cell == null) {
						continue;
					}
					// 取得每列的内容,如果列内容是$key$格式,则替换内容
					key = cell.getStringCellValue();
					if (key.indexOf("$") != -1 || key.indexOf("#list#") != -1) {
						// * 列中内容有#list#,则表示该行为模板行,需要以该行为模板
						// * 例如:模板行格式 #list#0_0 $Car.id$
						// * 第一个0表示需要在list中取iterator的索引值
						// * 第二个0表示在iterator中取的第几个对象,如果不为0,则取下一个对象,而不是沿用前面获取的对象
						// * $Car.id$表示所取的对象为Car的对象,并且取值为id的值
						if (key.indexOf("#list#") != -1) {
							key = key.replace("#list#", "").trim();
							String[] lists = key.split(" ");
							// 取得list中的索引值
							int listIndex = Integer
									.valueOf(lists[0].split("_")[0]);
							Iterator<?> iterator = list.get(listIndex);
							// 根据模板创建行并填弃数据,返回增加的行数
							int rowCount = iteratorFillCellValue(wb, sheet,
									cell, iterator, i, rowNum, key);
							rowNum += rowCount;
							i += rowCount;
							break;
						} else {
							// 直接填充数据的列,从对象数组中取得值
							getValueAndSetCellValue(cell, key, tArray);
						}
					}

				}
			}
			// 创建目标文件夹
			createFolder(targetPath);
			// 输出文件
			FileOutputStream fileOut = new FileOutputStream(targetPath);
			wb.write(fileOut);
			fileOut.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 根据iterator,以及模板中的标识,填充模板
	 * 
	 * @param wb
	 * @param sheet
	 * @param cell
	 * @param iterator
	 *            iterator
	 * @param index
	 *            模板行索引
	 * @param rowNum
	 *            表格总行数
	 * @param key
	 *            表格内容
	 * @return
	 */
	private int iteratorFillCellValue(HSSFWorkbook wb, HSSFSheet sheet,
			HSSFCell cell, Iterator<?> iterator, int index, int rowNum,
			String key) {
		int rowCount = 0;
		Object obj = null;
		int p = 0;
		int i = index;
		HSSFRow newRow = null;
		int tmpCellNum = 0;
		int k = 0;
		// 取得模板行
		HSSFRow orgRow = sheet.getRow(index);
		try {
			while (iterator.hasNext()) {
				// 取得iterator的对象
				obj = iterator.next();
				// 移动当前编辑行以下的所有行
				if (p != 0) {
					rowNum += 1;
					i += 1;
					rowCount += 1;// 增加的总行数
					// 把当前行以下的所有行往下移动1行
					sheet.shiftRows(i, rowNum, 1);
				}
				p = 1;
				// 创建新行
				newRow = sheet.createRow(index + k++);
				// 把新行的内容换成和模板行一样
				copyRow(wb, orgRow, newRow, true);
				tmpCellNum = newRow.getLastCellNum();
				for (int l = 0; l < tmpCellNum; l++) {
					cell = newRow.getCell(l);
					key = cell.getStringCellValue();
					/**
					 * 如果单无格内容为#list#,表示该行是模板行 #list#0_0
					 * 第一个0表示需要在list中取iterator的索引值
					 * 第二个0表示在iterator中取的第几个对象,如果不为0,则取下一个对象,而不是沿用前面获取的对象
					 */
					if (key.indexOf("#list#") != -1 && key.indexOf("_0") == -1) {
						if (iterator.hasNext()) {
							obj = iterator.next();
						} else {
							obj = null;
						}
					}
					if (key.trim().indexOf(" ") != -1) {
						key = key.split(" ")[1];
					}
					getValueAndSetCellValue(cell, key, obj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rowCount;
	}

	/**
	 * 取到相应的值并填入相应的列中
	 * 
	 * @param cell
	 *            列
	 * @param key
	 *            列内容
	 * @param obj
	 *            数据源对象
	 */
	private void getValueAndSetCellValue(HSSFCell cell, String key, Object obj) {
		try {
			// 保有存单元格的内容
			String cellValue = key = key.replace("\\n", "");
			String tmpKey;
			// 循环截取两个$中间的内容,反射出值
			while (key.indexOf("$") != -1) {
				key = key.substring(key.indexOf("$") + 1);
				// 取两个$中间的内容
				tmpKey = key.substring(0, key.indexOf("$"));
				key = key.substring(key.indexOf("$") + 1);
				// 如果内容是如下格式Cars.id,则从obj中值得相应的对象的值
				if (tmpKey.indexOf(".") != -1) {
					String className = tmpKey.substring(0, tmpKey.indexOf("."));
					// 取得类的全限定名
					String classWholeName = packaegName + className;
					String fieldName = tmpKey.substring(tmpKey.indexOf(".") + 1);
					// 如果obj是数组,循环判断哪个对象是对应的
					if (obj instanceof Object[]) {
						Object[] objs = (Object[]) obj;
						for (int k = 0; k < objs.length; k++) {
							if (objs[k].getClass().getName().equals(classWholeName)) {
								cellValue = cellValue.replace("$" + tmpKey
										+ "$", getKeyValue(objs[k], fieldName)
										+ "");
							}
						}
					} else if (obj.getClass().getName().equals(classWholeName)) {
						cellValue = cellValue.replace("$" + tmpKey + "$",getKeyValue(obj, fieldName) + "");
					}
				}
			}
			cell.setCellValue(cellValue);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 给列填充数据
	 * 
	 * @param cell
	 *            列
	 * @param obj
	 *            数据源对象
	 * @param fieldName
	 *            需要取数据的字段
	 */
	private Object getKeyValue(Object obj, String fieldName) {
		Object value = "";
		try {
			if (obj != null) {
				ReportRelatedUtils test = new ReportRelatedUtils();
				value = test.getValue(obj, fieldName) == null ? "" : test .getValue(obj, fieldName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return value;
	}

	public static void main(String[] args) {

		try {
			ReportUtils ee = new ReportUtils();
			List<Iterator<?>> list = new ArrayList<Iterator<?>>();
			Line line = new Line();
			line.setId(1);
			line.setName("line1");

			List<Object> dataList = new ArrayList<Object>();
			

			ScheduleRealInfo srr = new ScheduleRealInfo();
			srr.setId((long) 111);
			srr.setXlName("abc11");
			
			ScheduleRealInfo sr = new ScheduleRealInfo();
			sr.setId((long) 22);
			sr.setXlName("abc22");
			dataList.add(sr);
			sr = new ScheduleRealInfo();
			sr.setId((long) 33);
			sr.setXlName("abc33");
			dataList.add(sr);
			list.add(dataList.iterator());
			
			ee.excelReplace(list, new Object[] { srr }, "D:\\55.xls",
					"D:\\22.xls");
			System.out.println("ok");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 行复制功能
	 * 
	 * @param fromRow
	 * @param toRow
	 */
	private void copyRow(HSSFWorkbook wb, HSSFRow fromRow, HSSFRow toRow,
			boolean copyValueFlag) {
		for (Iterator<Cell> cellIt = fromRow.cellIterator(); cellIt.hasNext();) {
			HSSFCell tmpCell = (HSSFCell) cellIt.next();
			HSSFCell newCell = toRow.createCell(tmpCell.getColumnIndex(), 0);
			copyCell(wb, tmpCell, newCell, copyValueFlag);
		}
	}

	/**
	 * 复制单元格
	 * 
	 * @param srcCell
	 * @param distCell
	 * @param copyValueFlag
	 *            true则连同cell的内容一起复制
	 */
	public void copyCell(HSSFWorkbook wb, HSSFCell srcCell, HSSFCell distCell,
			boolean copyValueFlag) {
		HSSFCellStyle newstyle = wb.createCellStyle();
		copyCellStyle(wb, srcCell.getCellStyle(), newstyle);
		// 样式
		distCell.setCellStyle(newstyle);
		// 评论
		if (srcCell.getCellComment() != null) {
			distCell.setCellComment(srcCell.getCellComment());
		}
		// 不同数据类型处理
		int srcCellType = srcCell.getCellType();
		distCell.setCellType(srcCellType);
		if (copyValueFlag) {
			if (srcCellType == HSSFCell.CELL_TYPE_NUMERIC) {
				distCell.setCellValue(srcCell.getDateCellValue());
			} else if (srcCellType == HSSFCell.CELL_TYPE_STRING) {
				distCell.setCellValue(srcCell.getRichStringCellValue());
			} else if (srcCellType == HSSFCell.CELL_TYPE_BLANK) {

			} else if (srcCellType == HSSFCell.CELL_TYPE_BOOLEAN) {
				distCell.setCellValue(srcCell.getBooleanCellValue());
			} else if (srcCellType == HSSFCell.CELL_TYPE_ERROR) {
				distCell.setCellErrorValue(srcCell.getErrorCellValue());
			} else if (srcCellType == HSSFCell.CELL_TYPE_FORMULA) {
				distCell.setCellFormula(srcCell.getCellFormula());
			} else {
			}
		}
	}

	/**
	 * 复制一个单元格样式到目的单元格样式
	 * 
	 * @param fromStyle
	 * @param toStyle
	 */
	public void copyCellStyle(HSSFWorkbook wb, HSSFCellStyle fromStyle,
			HSSFCellStyle toStyle) {
		toStyle.setAlignment(fromStyle.getAlignment());
		// 边框和边框颜色
		toStyle.setBorderBottom(fromStyle.getBorderBottom());
		toStyle.setBorderLeft(fromStyle.getBorderLeft());
		toStyle.setBorderRight(fromStyle.getBorderRight());
		toStyle.setBorderTop(fromStyle.getBorderTop());
		toStyle.setTopBorderColor(fromStyle.getTopBorderColor());
		toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
		toStyle.setRightBorderColor(fromStyle.getRightBorderColor());
		toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());

		// 背景和前景
		toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());
		toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());

		toStyle.setDataFormat(fromStyle.getDataFormat());
		toStyle.setFillPattern(fromStyle.getFillPattern());
		toStyle.setHidden(fromStyle.getHidden());
		toStyle.setIndention(fromStyle.getIndention());// 首行缩进
		toStyle.setLocked(fromStyle.getLocked());
		toStyle.setRotation(fromStyle.getRotation());// 旋转
		toStyle.setVerticalAlignment(fromStyle.getVerticalAlignment());
		toStyle.setWrapText(fromStyle.getWrapText());
		// 字体
		toStyle.setFont(fromStyle.getFont(wb));

	}

	/**
	 * 创建文件夹,并删除原有文件
	 * 
	 * @param path
	 */
	private void createFolder(String path) {
		File targetFile = null;
		targetFile = new File(path);
		if (targetFile.exists()) {// 删除原有文件
			targetFile.delete();
		}
		// 创建目标文件夹
		targetFile = new File(path.substring(0, path.lastIndexOf("\\")));
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}
	}

}