现在很多java企业级应用要求进行数据在Excel上的操作,比较常用的技术是jxl和poi,对比而言两者都是比较简单实用,但在实现下拉列表功能上,jxl的功能接口没有poi的完善,比如实现下拉列表联动技术,就是poi比较简单好用,目前还在网上没有找到能够用jxl实现这个功能,希望读者能够仔细阅读jxl api,以求找到实现这一功能的接口。下面我来大概罗列用poi实现下拉列表联动的思路,然后贴出代码。
1.创建一个要显示的shee1t,并将非下拉框的数据依次写入sheet中,下拉框的数据要另外处理;
2.创建一个隐藏的sheet2,用于规律存放下拉框的数据,以行为单位,要计算关联的范围,记住sheet1的下拉框是和sheet2的数据关联的;
3.设置关联;
4.设置下拉框并可以增加下拉框操作验证;
主要核心代码:
package com.pccw.custom.ln.fas.ar.test;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import com.pccw.business.fas.ap.utils.excel.upload.UploadMappingCell;
import com.pccw.business.fas.ap.utils.excel.upload.UploadMappingReader;
import com.pccw.custom.ln.fas.ar.vo.SalesTaxAjustmentInfo;
import com.pccw.kernel.util.SystemProperties;
public class ExcelSelectUtils {
private static String EXCEL_HIDE_SHEET_NAME = "excelhidesheetname";
private static String HIDE_SHEET_NAME_LINE = "lineType";
private HashMap map = new HashMap();
private static String[] lineType = {"line","tax"};
private static String[] difReasonLine = {"line","a","b","c","d","e"};
private static String[] difReasonTax = {"tax","f","g","h","i","j)"};
private static CellStyle getTitleStyle(Workbook wb){
CellStyle style = wb.createCellStyle();
//对齐方式设置
style.setAlignment(CellStyle.ALIGN_CENTER);
//边框颜色和宽度设置
style.setBorderBottom(CellStyle.BORDER_THIN);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderRight(CellStyle.BORDER_THIN);
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderTop(CellStyle.BORDER_THIN);
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
style.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
//设置背景颜色
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
//粗体字设置
Font font = wb.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(font);
return style;
}
/**
* 创建一列数据
* @param currentRow
* @param textList
*/
private static void creatRow(Row currentRow,String[] textList){
if(textList!=null&&textList.length>0){
int i = 0;
for(String cellValue : textList){
Cell userNameLableCell = currentRow.createCell(i++);
userNameLableCell.setCellValue(cellValue);
}
}
}
/**
* 名称数据行列计算表达式
* @param order
* @param size
* @param cascadeFlag
* @return
*/
private static String creatExcelNameList(int order,int size,boolean cascadeFlag){
char start = 'A';
if(cascadeFlag){
start = 'B';
if(size<=25){
char end = (char)(start+size-1);
return "$"+start+"$"+order+":$"+end+"$"+order;
}else{
char endPrefix = 'A';
char endSuffix = 'A';
if((size-25)/26==0||size==51){//26-51之间,包括边界(仅两次字母表计算)
if((size-25)%26==0){//边界值
endSuffix = (char)('A'+25);
}else{
endSuffix = (char)('A'+(size-25)%26-1);
}
}else{//51以上
if((size-25)%26==0){
endSuffix = (char)('A'+25);
endPrefix = (char)(endPrefix + (size-25)/26 - 1);
}else{
endSuffix = (char)('A'+(size-25)%26-1);
endPrefix = (char)(endPrefix + (size-25)/26);
}
}
return "$"+start+"$"+order+":$"+endPrefix+endSuffix+"$"+order;
}
}else{
if(size<=26){
char end = (char)(start+size-1);
return "$"+start+"$"+order+":$"+end+"$"+order;
}else{
char endPrefix = 'A';
char endSuffix = 'A';
if(size%26==0){
endSuffix = (char)('A'+25);
if(size>52&&size/26>0){
endPrefix = (char)(endPrefix + size/26-2);
}
}else{
endSuffix = (char)('A'+size%26-1);
if(size>52&&size/26>0){
endPrefix = (char)(endPrefix + size/26-1);
}
}
return "$"+start+"$"+order+":$"+endPrefix+endSuffix+"$"+order;
}
}
}
private static DataValidation getDataValidationByFormula(String formulaString,int naturalRowIndex,int naturalColumnIndex){
//加载下拉列表内容
DVConstraint constraint = DVConstraint.createFormulaListConstraint(formulaString);
//设置数据有效性加载在哪个单元格上。
//四个参数分别是:起始行、终止行、起始列、终止列
int firstRow = naturalRowIndex-1;
int lastRow = naturalRowIndex-1;
int firstCol = naturalColumnIndex-1;
int lastCol = naturalColumnIndex-1;
CellRangeAddressList regions=new CellRangeAddressList(firstRow,lastRow,firstCol,lastCol);
//数据有效性对象
DataValidation data_validation_list = new HSSFDataValidation(regions,constraint);
//设置输入信息提示信息
data_validation_list.createPromptBox("下拉选择提示","请使用下拉方式选择合适的值!");
//设置输入错误提示信息
data_validation_list.createErrorBox("选择错误提示","你输入的值未在备选列表中,请下拉选择合适的值!");
return data_validation_list;
}
public static void setDataValidation(Workbook wb, int listSize){
int sheetIndex = wb.getNumberOfSheets();
if(sheetIndex>0){
for(int i=0;i
if(!EXCEL_HIDE_SHEET_NAME.equals(sheet.getSheetName())){
DataValidation data_validation_list = null;
for(int a=2; a
data_validation_list = getDataValidationByFormula(HIDE_SHEET_NAME_LINE,a,5);
sheet.addValidationData(data_validation_list);
//差异原因选项添加验证数据
data_validation_list = getDataValidationByFormula("INDIRECT(E"+a+")",a,13);
sheet.addValidationData(data_validation_list);
}
}
}
}
}
/**
* 创建一个名称
* @param workbook
* @param nameCode
* @param order
* @param size
* @param cascadeFlag
*/
private static void creatExcelNameList(Workbook workbook,String nameCode,int order,int size,boolean cascadeFlag){
Name name;
name = workbook.createName();
name.setNameName(nameCode);
name.setRefersToFormula(EXCEL_HIDE_SHEET_NAME+"!"+creatExcelNameList(order,size,cascadeFlag));
}
public static File getSelectExcels(String sheetName, List list, Class cls){
File file = null;
sheetName = StringUtils.isNotBlank(sheetName) ? sheetName : "Sheet 1";
if(list != null && list.size() >0){
List mappingList = UploadMappingReader.getSheetMapping(cls.getName(), "1");
Workbook wb = null;
if (mappingList != null && mappingList.size() > 0) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String fileName =SystemProperties.get("fas.download.temp") + fmt.format(new Date()) + ".xls";
file = new File(fileName);
int rowIndex = 0;
Map attrMap = new HashMap();
try{
//POI创建表格
wb = new HSSFWorkbook();
//创建标题行
//createExcelMo(wb,mappingList,sheetName,rowIndex);
Sheet sheet = wb.createSheet(sheetName); //创建一个sheet
Row row = sheet.createRow(rowIndex);
for(int column=0; column
Cell cell = row.createCell(column);
cell.setCellStyle(getTitleStyle(wb));
cell.setCellValue(headerCell.getHeader());//列名
attrMap.put("" + column, headerCell.getAttribute());
}
rowIndex++; //换行
//循环单元格赋值
for(int i=0; i
SalesTaxAjustmentInfo sat = (SalesTaxAjustmentInfo) obj;
//Row currentRow = hideInfoSheet.createRow(rowIndex);
Row currentRow = sheet.createRow(rowIndex);
for(int column = 0; column < attrMap.size();column++){
Cell cell = currentRow.createCell(column);
String value = "";
String attribute = (String) attrMap.get("" + column);
value = BeanUtils.getProperty(obj, attribute);
cell.setCellValue(value);
}
rowIndex++;
}
//建立级联下拉框关联
Sheet hideInfoSheet = wb.createSheet(EXCEL_HIDE_SHEET_NAME); //联动隐藏
Row lineTypeRow = hideInfoSheet.createRow(0); //行类型
creatRow(lineTypeRow, lineType);
Row difReasonLineRow = hideInfoSheet.createRow(1);
creatRow(difReasonLineRow, difReasonLine);
Row difReasonTaxRow = hideInfoSheet.createRow(2);
creatRow(difReasonTaxRow, difReasonTax);
//名称管理
creatExcelNameList(wb, HIDE_SHEET_NAME_LINE, 1, lineType.length, false);
//动态设置对应类型的原因列表
creatExcelNameList(wb, lineType[0], 2, difReasonLine.length, true);
creatExcelNameList(wb, lineType[1], 3, difReasonTax.length, true);
//设置隐藏页标志
wb.setSheetHidden(wb.getSheetIndex(EXCEL_HIDE_SHEET_NAME), true);
//增加下拉框并增加数据验证
int listSize = list.size();
setDataValidation(wb,listSize);
}catch(Exception e){
e.printStackTrace();
}
}
FileOutputStream fileOut;
try {
fileOut = new FileOutputStream(file);
wb.write(fileOut);
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
};
}