效果图
代码:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
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.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.util.CellRangeAddressList;
public class TestW {
private static final String MAIN_SHEET_NAME = "template";
private static final String HIDDEN_SHEET1_NAME = "hidden1";
private static final String DEVICE_NAMES = "devices";
private static final String DEVICE_TYPE_NAMES = "deviceTypes";
public static String getTimeStamp(){
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmssSSS");
return sdf.format(new Date());
}
public static void main(String[] args) {
FileOutputStream out = null;
File file;
try {
file = new File("D:/hhh"+getTimeStamp()+".xls"); //写文件
out = new FileOutputStream(file);
HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄
HSSFSheet mainSheet = wb.createSheet(MAIN_SHEET_NAME);
HSSFSheet dtHiddenSheet = wb.createSheet(HIDDEN_SHEET1_NAME);
HSSFRow rowFirst = mainSheet.createRow(3);//第几行(从0开始)
HSSFCell cell = rowFirst.createCell(3); //第几列(从0开始)
cell.setCellValue("年级"); //往单元格里写数据
HSSFCell cell2 = rowFirst.createCell(4); //第几列(从0开始)
cell2.setCellValue("班级"); //往单元格里写数据
List devices = Arrays.asList("1年级", "2年级", "3年级", "4年级");
List deviceTypes = Arrays.asList("1班", "2班", "3班");
initDevicesAndType02(wb, dtHiddenSheet, devices, deviceTypes);
DataValidation deviceValidation = getDataValidationByFormula04_01(DEVICE_NAMES,4,4,3,3);
DataValidation deviceTypeValidation = getDataValidationByFormula04_01(DEVICE_TYPE_NAMES,4,4,4, 4);
// 主sheet添加验证数据
mainSheet.addValidationData(deviceValidation);
mainSheet.addValidationData(deviceTypeValidation);
out.flush();
wb.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null)
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 生成下拉框及提示
* @param formulaString
* @param columnIndex
* @return
*/
public static DataValidation getDataValidationByFormula04_01(String formulaString,int firstRow, int lastRow, int firstCol, int lastCol) {
// 加载下拉列表内容
DVConstraint constraint = DVConstraint.createFormulaListConstraint(formulaString);
// 设置数据有效性加载在哪个单元格上。
// 四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
// 数据有效性对象
DataValidation dataValidationList = new HSSFDataValidation(regions, constraint);
dataValidationList.createErrorBox("Error", "请选择或输入有效的选项,或下载最新模版重试!");
return dataValidationList;
}
private static void initDevicesAndType02(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List devices, List deviceTypes) {
writeDevices02_01(wb, dtHiddenSheet, devices);
writeDeviceTypes02_02(wb, dtHiddenSheet, deviceTypes);
initDevicesNameMapping02_03(wb, dtHiddenSheet.getSheetName(), devices.size());
initDeviceTypesNameMapping02_04(wb, dtHiddenSheet.getSheetName(), deviceTypes.size());
}
private static void writeDevices02_01(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List devices) {
for (int i = 0; i < devices.size(); i++) {
HSSFRow row = dtHiddenSheet.createRow(i);
HSSFCell cell1 = row.createCell(0);
cell1.setCellValue(devices.get(i));
}
}
private static void writeDeviceTypes02_02(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List deviceTypes) {
int lastRow = dtHiddenSheet.getLastRowNum();
if(lastRow == 0 && dtHiddenSheet.getRow(0) == null )
dtHiddenSheet.createRow(0);
if (CollectionUtils.isNotEmpty(deviceTypes))
for (int j = 0; j < deviceTypes.size(); j++) {
if (j <= lastRow) { //前面创建过的行,直接获取行,创建列
dtHiddenSheet.getRow(j).createCell(1).setCellValue(deviceTypes.get(j)); //设置对应单元格的值
} else { //未创建过的行,直接创建行、创建列
dtHiddenSheet.setColumnWidth(j, 4000); //设置每列的列宽
//创建行、创建列
dtHiddenSheet.createRow(j).createCell(1).setCellValue(deviceTypes.get(j)); //设置对应单元格的值
}
}
}
private static void initDevicesNameMapping02_03(HSSFWorkbook workbook, String dtHiddenSheetName, int deviceQuantity) {
Name name = workbook.createName();
name.setNameName(DEVICE_NAMES);
name.setRefersToFormula(dtHiddenSheetName + "!$A$1:$A$" + deviceQuantity);
}
private static void initDeviceTypesNameMapping02_04(HSSFWorkbook wb, String dtHiddenSheetName, int deviceTypeQuantity) {
Name name = wb.createName();
name.setNameName(DEVICE_TYPE_NAMES);
name.setRefersToFormula(dtHiddenSheetName + "!$B$1:$B$" + deviceTypeQuantity);
}
}
相关阅读,级联下拉框
作者:Created by [email protected] on 2017/11/14.
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by [email protected] on 2017/11/14.
* poi version: poi-3.10-FINAL-20140208
*/
public class W2 {
private static final int XLS_MAX_ROW = 65535; //0开始
private static final String MAIN_SHEET_NAME = "template";
private static final String HIDDEN_SHEET1_NAME = "hidden1";
private static final String HIDDEN_SHEET2_NAME = "hidden2";
private static final String WAREHOUSE_NAMES = "warehouses";
private static final String DEVICE_NAMES = "devices";
private static final String DEVICE_TYPE_NAMES = "deviceTypes";
/**
* 创建入库excel模版
* @param filePath
* @param headers
* @param devices
* @param deviceTypes
* @param warehouses
* @param warehouseAndShelves
* @return
* @throws IOException
*/
private static File createStoreInExcelTemplate(String filePath, List headers,
List devices, List deviceTypes, List warehouses,
Map> warehouseAndShelves) throws IOException {
FileOutputStream out = null;
File file;
try {
file = new File(filePath); //写文件
// file = File.createTempFile("入库数据模版", ".xls");
out = new FileOutputStream(file);
HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄
HSSFSheet mainSheet = wb.createSheet(MAIN_SHEET_NAME);
HSSFSheet dtHiddenSheet = wb.createSheet(HIDDEN_SHEET1_NAME);
HSSFSheet wsHiddenSheet = wb.createSheet(HIDDEN_SHEET2_NAME);
// wb.setSheetHidden(1, true); //将第二个用于存储下拉框数据的sheet隐藏
// wb.setSheetHidden(2, true);
initHeaders01(wb, mainSheet, headers);
initDevicesAndType02(wb, dtHiddenSheet, devices, deviceTypes);
initWarehousesAndShelves03(wb, wsHiddenSheet, warehouses, warehouseAndShelves);
initSheetNameMapping04(mainSheet);
initOtherConstraints05(mainSheet);
out.flush();
wb.write(out);
// file.deleteOnExit();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (out != null)
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
/**
* 初始化仓库&货架下拉框数据
*
* @param workbook
* @param wsSheet
* @param warehouses
* @param warehousesAndShelves
*/
private static void initWarehousesAndShelves03(HSSFWorkbook workbook, HSSFSheet wsSheet, List warehouses, Map> warehousesAndShelves) {
writeWarehouses03_01(workbook, wsSheet, warehouses);
writeShelves03_02(workbook, wsSheet, warehouses, warehousesAndShelves);
initWarehouseNameMapping03_03(workbook, wsSheet.getSheetName(), warehouses.size());
}
/**
* 在隐藏sheet中写入库房下拉框数据
*
* @param workbook
* @param wsSheet
* @param warehouses
*/
private static void writeWarehouses03_01(HSSFWorkbook workbook, HSSFSheet wsSheet, List warehouses) {
for (int i = 0; i < warehouses.size(); i++) {
HSSFRow row = wsSheet.createRow(i);
HSSFCell cell = row.createCell(0);
cell.setCellValue(warehouses.get(i));
}
}
/**
* 在隐藏sheet中写入货架下拉框数据
*
* @param workbook
* @param wsSheet
* @param warehouses
* @param warehousesAndShelves
*/
private static void writeShelves03_02(HSSFWorkbook workbook, HSSFSheet wsSheet, List warehouses, Map> warehousesAndShelves) {
for (int i = 0; i < warehouses.size(); i++) {
int referColNum = i + 1;
String warehouseName = warehouses.get(i);
List shelves = warehousesAndShelves.get(warehouseName);
if (CollectionUtils.isNotEmpty(shelves)) {
int rowCount = wsSheet.getLastRowNum();
if(rowCount == 0 && wsSheet.getRow(0) == null ){
wsSheet.createRow(2);
}
for (int j = 0; j < shelves.size(); j++) {
if (j <= rowCount) { //前面创建过的行,直接获取行,创建列
wsSheet.getRow(j).createCell(referColNum).setCellValue(shelves.get(j)); //设置对应单元格的值
} else { //未创建过的行,直接创建行、创建列
wsSheet.setColumnWidth(j, 4000); //设置每列的列宽
//创建行、创建列
wsSheet.createRow(j).createCell(referColNum).setCellValue(shelves.get(j)); //设置对应单元格的值
}
}
}
initShelfNameMapping(workbook, wsSheet.getSheetName(), warehouseName, referColNum, shelves.size());
}
}
/**
* 初始化库房选择“名称”
*
* @param workbook
* @param wsSheetName
* @param warehouseQuantity
*/
private static void initWarehouseNameMapping03_03(HSSFWorkbook workbook, String wsSheetName, int warehouseQuantity) {
Name name = workbook.createName();
// 设置仓库名称
name.setNameName(WAREHOUSE_NAMES);
name.setRefersToFormula(wsSheetName + "!$A$1:$A$" + warehouseQuantity);
}
/**
* 货架与库房下拉选择数据关联
*
* @param workbook
* @param wsSheetName
* @param warehouseName
* @param referColNum
* @param shelfQuantity
*/
private static void initShelfNameMapping(HSSFWorkbook workbook, String wsSheetName, String warehouseName, int referColNum, int shelfQuantity) {
Name name = workbook.createName();
// 设置货架名称
name.setNameName(warehouseName);
String referColName = getColumnName(referColNum);
String formula = wsSheetName + "!$" + referColName + "$1:$" + referColName + "$" + shelfQuantity;
name.setRefersToFormula(formula);
}
/**
* 根据数据值确定单元格位置(比如:0-A, 27-AB)
*
* @param index
* @return
*/
public static String getColumnName(int index) {
StringBuilder s = new StringBuilder();
while (index >= 26) {
s.insert(0, (char) ('A' + index % 26));
index = index / 26 - 1;
}
s.insert(0, (char) ('A' + index));
return s.toString();
}
private static void initDevicesAndType02(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List devices, List deviceTypes) {
writeDevices02_01(wb, dtHiddenSheet, devices);
writeDeviceTypes02_02(wb, dtHiddenSheet, deviceTypes);
initDevicesNameMapping02_03(wb, dtHiddenSheet.getSheetName(), devices.size());
initDeviceTypesNameMapping02_04(wb, dtHiddenSheet.getSheetName(), deviceTypes.size());
}
private static void writeDevices02_01(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List devices) {
for (int i = 0; i < devices.size(); i++) {
HSSFRow row = dtHiddenSheet.createRow(i);
HSSFCell cell1 = row.createCell(0);
cell1.setCellValue(devices.get(i));
}
}
private static void writeDeviceTypes02_02(HSSFWorkbook wb, HSSFSheet dtHiddenSheet, List deviceTypes) {
int lastRow = dtHiddenSheet.getLastRowNum();
if(lastRow == 0 && dtHiddenSheet.getRow(0) == null )
dtHiddenSheet.createRow(0);
if (CollectionUtils.isNotEmpty(deviceTypes))
for (int j = 0; j < deviceTypes.size(); j++) {
if (j <= lastRow) { //前面创建过的行,直接获取行,创建列
dtHiddenSheet.getRow(j).createCell(1).setCellValue(deviceTypes.get(j)); //设置对应单元格的值
} else { //未创建过的行,直接创建行、创建列
dtHiddenSheet.setColumnWidth(j, 4000); //设置每列的列宽
//创建行、创建列
dtHiddenSheet.createRow(j).createCell(1).setCellValue(deviceTypes.get(j)); //设置对应单元格的值
}
}
}
private static void initDevicesNameMapping02_03(HSSFWorkbook workbook, String dtHiddenSheetName, int deviceQuantity) {
Name name = workbook.createName();
// 设置设备“名称”
name.setNameName(DEVICE_NAMES);
name.setRefersToFormula(dtHiddenSheetName + "!$A$1:$A$" + deviceQuantity);
}
private static void initDeviceTypesNameMapping02_04(HSSFWorkbook wb, String dtHiddenSheetName, int deviceTypeQuantity) {
Name name = wb.createName();
// 设置设备“名称”
name.setNameName(DEVICE_TYPE_NAMES);
name.setRefersToFormula(dtHiddenSheetName + "!$B$1:$B$" + deviceTypeQuantity);
}
/**
* 初始化表头
*
* @param wb
* @param mainSheet
* @param headers
*/
private static void initHeaders01(HSSFWorkbook wb, HSSFSheet mainSheet, List headers) {
//表头样式
HSSFCellStyle style = wb.createCellStyle();
//style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
style.setAlignment(HorizontalAlignment.CENTER);
//字体样式
HSSFFont fontStyle = wb.createFont();
fontStyle.setFontName("微软雅黑");
fontStyle.setFontHeightInPoints((short) 12);
// fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
fontStyle.setBold(true);
style.setFont(fontStyle);
//生成sheet1内容
HSSFRow rowFirst = mainSheet.createRow(0);//第一个sheet的第一行为标题
mainSheet.createFreezePane(0, 1, 0, 1); //冻结第一行
//写标题
for (int i = 0; i < headers.size(); i++) {
HSSFCell cell = rowFirst.createCell(i); //获取第一行的每个单元格
mainSheet.setColumnWidth(i, 4000); //设置每列的列宽
cell.setCellStyle(style); //加样式
cell.setCellValue(headers.get(i)); //往单元格里写数据
}
}
/**
* 主sheet中下拉框初始化
*
* @param mainSheet
*/
private static void initSheetNameMapping04(HSSFSheet mainSheet) {
DataValidation deviceValidation = getDataValidationByFormula04_01(DEVICE_NAMES, 0);
DataValidation deviceTypeValidation = getDataValidationByFormula04_01(DEVICE_TYPE_NAMES, 1);
DataValidation warehouseValidation = getDataValidationByFormula04_01(WAREHOUSE_NAMES, 3);
DataValidation shelfValidation = getDataValidationByFormula04_01("INDIRECT($D1)", 4); //formula同"INDIRECT(INDIRECT(\"R\"&ROW()&\"C\"&(COLUMN()-1),FALSE))"
// 主sheet添加验证数据
mainSheet.addValidationData(warehouseValidation);
mainSheet.addValidationData(shelfValidation);
mainSheet.addValidationData(deviceValidation);
mainSheet.addValidationData(deviceTypeValidation);
}
/**
* 初始化其他列输入限定
*
* @param mainSheet
*/
private static void initOtherConstraints05(HSSFSheet mainSheet) {
DataValidation quantityValidation = getDecimalValidation05_01(1, XLS_MAX_ROW, 2);
DataValidation tierValidation = getDecimalValidation05_01(1, XLS_MAX_ROW, 5);
DataValidation colValidation = getDecimalValidation05_01(1, XLS_MAX_ROW, 6);
mainSheet.addValidationData(tierValidation);
mainSheet.addValidationData(colValidation);
mainSheet.addValidationData(quantityValidation);
}
/**
* 数字输入验证
* @param firstRow
* @param lastRow
* @param columnIndex
* @return
*/
private static DataValidation getDecimalValidation05_01(int firstRow, int lastRow, int columnIndex) {
// 创建一个规则:>0的整数
DVConstraint constraint = DVConstraint.createNumericConstraint(DVConstraint.ValidationType.INTEGER, DVConstraint.OperatorType.GREATER_OR_EQUAL, "0", "0");
// 设定在哪个单元格生效
CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, columnIndex, columnIndex);
// 创建规则对象
HSSFDataValidation decimalVal = new HSSFDataValidation(regions, constraint);
decimalVal.createPromptBox("", initPromptText(columnIndex));
decimalVal.createErrorBox("输入值类型或大小有误!", "数值型,请输入大于0 的整数。");
return decimalVal;
}
/**
* 生成下拉框及提示
*
* @param formulaString
* @param columnIndex
* @return
*/
public static DataValidation getDataValidationByFormula04_01(String formulaString, int columnIndex) {
// 加载下拉列表内容
DVConstraint constraint = DVConstraint.createFormulaListConstraint(formulaString);
// 设置数据有效性加载在哪个单元格上。
// 四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(1, XLS_MAX_ROW, columnIndex, columnIndex);
// 数据有效性对象
DataValidation dataValidationList = new HSSFDataValidation(regions, constraint);
dataValidationList.createErrorBox("Error", "请选择或输入有效的选项,或下载最新模版重试!");
String promptText = initPromptText(columnIndex);
dataValidationList.createPromptBox("", promptText);
return dataValidationList;
}
/**
* 初始化下拉框提示信息
*
* @param columnIndex
* @return
*/
private static String initPromptText(int columnIndex) {
String promptText ="";
//custom column prompt
switch (columnIndex) {
case 2:
promptText = "请输入大于0的整数!";
break;
case 4:
promptText = "请下拉选择或输入有效项!且先选择库房!";
break;
case 5:
promptText = "请输入大于0的整数!";
break;
case 6:
promptText = "请输入大于0的整数!";
break;
}
return promptText;
}
public static File test() throws IOException {
//************* mock data ************
List headers = Arrays.asList("设备名称", "设类型", "数量", "存放库房", "存放货架", "存放层", "存放列");
List deviceTypes = Arrays.asList("type1", "type2", "type3", "type4");
List devices = Arrays.asList("设备1", "设备2", "设备3");
List warehouses = Arrays.asList("库房1", "库房2");
Map> warehousesAndShelves = new HashMap<>();
warehousesAndShelves.put("库房1", Arrays.asList("货架1-1", "货架1-2", "货架1-3"));
warehousesAndShelves.put("库房2", Arrays.asList("货架2-1", "货架2-2", "货架2-3"));
return W2.createStoreInExcelTemplate("D:/test"+getTimeStamp()+".xls", headers,devices, deviceTypes, warehouses, warehousesAndShelves);
}
public static void main(String[] args) throws IOException {
W2.test();
}
public static String getTimeStamp(){
// SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmssSSS");
return sdf.format(new Date());
}
}