使用 apache poi 对数千个单元格进行自定义数据验证
Custom Data Validation to thousands of cells using apache poi
我正在 Java 中创建一个 excel sheet,它有超过 10k 条记录。对于特定列,我想对该列中的所有单元格设置验证,它可以是“NEW_RULE-x”类型,其中 x >= 1 (NEW_RULE-1, NEW_RULE-2,. ..等)或“x”型(1,2,...等)
所以在 excel 中手动,我想出了将自定义验证应用于单元格(假设是 D3)的方法:
"=OR(AND(LEFT(D3,9)="NEW_RULE-",MID(D3,10,1)>="1"),OR(AND(D3>=1,D3<=999999) ))”。
如果我想将它应用于 D4,则验证公式将包含 D4 而不是 D3。他们是对整个 D 列执行此操作的通用方法吗,这样我就不必在迭代记录时为 Java 代码中的每个单元格申请?下面是生成快速 excel sheet 并在 D3 单元格进行数据验证的代码。
String filePath = "D\mysheet.xlsx";
File file = new File(filePath);
XSSFWorkbook workbook = new XSSFWorkbook();
FileOutputStream fos;
try {
XSSFSheet sheet = workbook.createSheet();
for (int i = 0; i <= 5; i++) {
XSSFRow row = sheet.getRow(i);
if(row == null)
row = sheet.createRow(i);
XSSFCell cell=row.getCell(0);
if(cell == null)
cell = row.createCell(0, XSSFCell.CELL_TYPE_STRING);
cell.setCellValue("Keyword" +i);
cell=row.getCell(1);
if(cell == null)
cell = row.createCell(1, XSSFCell.CELL_TYPE_STRING);
cell.setCellValue("PASS" +i);
System.out.println("1");
}
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createCustomConstraint(
"=OR(AND(LEFT(D3,9)=\"NEW_RULE-\",MID(D3,10,1)>=\"1\"),OR(AND(D3>=1,D3<=999999)))");
//=OR(AND(LEFT(D3,9)="NEW_RULE-",MID(D3,10,1)>="1"),OR(AND(D3>=1,D3<=999999)))
CellRangeAddressList addressList = new CellRangeAddressList(2,2,3,3);
XSSFDataValidation dataValidation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);
sheet.addValidationData(dataValidation);
fos = new FileOutputStream(filePath);
workbook.write(fos);
fos.close();
}finally{
}
}```
首先:通过apache poi
设置公式字符串时,不要将等号=
放在前面。等号不存储在 Excel
的存储中。它仅在 GUI
.
中可见
当使用公式时,即使在条件格式和数据验证中,单元格引用也可以是相对的或绝对的。例如 A1
是相对引用,而 $A
是绝对引用。因此,由于您在公式中仅使用相对引用,因此引用将调整到 sheet 中的新单元格。例如,D1
单元格中的 LEFT(D1,9)="NEW_RULE-"
将是 D2
单元格中的 LEFT(D2,9)="NEW_RULE-"
和 D3
单元格中的 LEFT(D3,9)="NEW_RULE-"
等等。
因此公式字符串 "OR(AND(LEFT($D1,9)=\"NEW_RULE-\",MID($D1,10,1)>=\"1\"),OR(AND($D1>=1,$D1<=999999)))"
可用于单元格 D1:D1000
,并且对于绝对列 D
.
中的当前相对行始终是正确的
完整示例:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddressList;
class CreateExcelDataValidation {
public static void main(String[] args) throws Exception {
//Workbook workbook = new HSSFWorkbook(); String filePath = "./mysheet.xls";
Workbook workbook = new XSSFWorkbook(); String filePath = "./mysheet.xlsx";
Sheet sheet = workbook.createSheet();
for (int i = 0; i <= 5; i++) {
Row row = sheet.getRow(i);
if (row == null) row = sheet.createRow(i);
Cell cell = row.getCell(0);
if (cell == null) cell = row.createCell(0);
cell.setCellValue("Keyword" +i);
cell = row.getCell(1);
if (cell == null) cell = row.createCell(1);
cell.setCellValue("PASS" +i);
}
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createCustomConstraint("OR(AND(LEFT($D1,9)=\"NEW_RULE-\",MID($D1,10,1)>=\"1\"),OR(AND($D1>=1,$D1<=999999)))");
CellRangeAddressList addressList = new CellRangeAddressList(0, 1000, 3, 3);
DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
if (workbook instanceof XSSFWorkbook) validation.setShowErrorBox(true);
sheet.addValidationData(validation);
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
workbook.close();
out.close();
}
}
我正在 Java 中创建一个 excel sheet,它有超过 10k 条记录。对于特定列,我想对该列中的所有单元格设置验证,它可以是“NEW_RULE-x”类型,其中 x >= 1 (NEW_RULE-1, NEW_RULE-2,. ..等)或“x”型(1,2,...等)
所以在 excel 中手动,我想出了将自定义验证应用于单元格(假设是 D3)的方法: "=OR(AND(LEFT(D3,9)="NEW_RULE-",MID(D3,10,1)>="1"),OR(AND(D3>=1,D3<=999999) ))”。 如果我想将它应用于 D4,则验证公式将包含 D4 而不是 D3。他们是对整个 D 列执行此操作的通用方法吗,这样我就不必在迭代记录时为 Java 代码中的每个单元格申请?下面是生成快速 excel sheet 并在 D3 单元格进行数据验证的代码。
String filePath = "D\mysheet.xlsx";
File file = new File(filePath);
XSSFWorkbook workbook = new XSSFWorkbook();
FileOutputStream fos;
try {
XSSFSheet sheet = workbook.createSheet();
for (int i = 0; i <= 5; i++) {
XSSFRow row = sheet.getRow(i);
if(row == null)
row = sheet.createRow(i);
XSSFCell cell=row.getCell(0);
if(cell == null)
cell = row.createCell(0, XSSFCell.CELL_TYPE_STRING);
cell.setCellValue("Keyword" +i);
cell=row.getCell(1);
if(cell == null)
cell = row.createCell(1, XSSFCell.CELL_TYPE_STRING);
cell.setCellValue("PASS" +i);
System.out.println("1");
}
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createCustomConstraint(
"=OR(AND(LEFT(D3,9)=\"NEW_RULE-\",MID(D3,10,1)>=\"1\"),OR(AND(D3>=1,D3<=999999)))");
//=OR(AND(LEFT(D3,9)="NEW_RULE-",MID(D3,10,1)>="1"),OR(AND(D3>=1,D3<=999999)))
CellRangeAddressList addressList = new CellRangeAddressList(2,2,3,3);
XSSFDataValidation dataValidation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);
sheet.addValidationData(dataValidation);
fos = new FileOutputStream(filePath);
workbook.write(fos);
fos.close();
}finally{
}
}```
首先:通过apache poi
设置公式字符串时,不要将等号=
放在前面。等号不存储在 Excel
的存储中。它仅在 GUI
.
当使用公式时,即使在条件格式和数据验证中,单元格引用也可以是相对的或绝对的。例如 A1
是相对引用,而 $A
是绝对引用。因此,由于您在公式中仅使用相对引用,因此引用将调整到 sheet 中的新单元格。例如,D1
单元格中的 LEFT(D1,9)="NEW_RULE-"
将是 D2
单元格中的 LEFT(D2,9)="NEW_RULE-"
和 D3
单元格中的 LEFT(D3,9)="NEW_RULE-"
等等。
因此公式字符串 "OR(AND(LEFT($D1,9)=\"NEW_RULE-\",MID($D1,10,1)>=\"1\"),OR(AND($D1>=1,$D1<=999999)))"
可用于单元格 D1:D1000
,并且对于绝对列 D
.
完整示例:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddressList;
class CreateExcelDataValidation {
public static void main(String[] args) throws Exception {
//Workbook workbook = new HSSFWorkbook(); String filePath = "./mysheet.xls";
Workbook workbook = new XSSFWorkbook(); String filePath = "./mysheet.xlsx";
Sheet sheet = workbook.createSheet();
for (int i = 0; i <= 5; i++) {
Row row = sheet.getRow(i);
if (row == null) row = sheet.createRow(i);
Cell cell = row.getCell(0);
if (cell == null) cell = row.createCell(0);
cell.setCellValue("Keyword" +i);
cell = row.getCell(1);
if (cell == null) cell = row.createCell(1);
cell.setCellValue("PASS" +i);
}
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createCustomConstraint("OR(AND(LEFT($D1,9)=\"NEW_RULE-\",MID($D1,10,1)>=\"1\"),OR(AND($D1>=1,$D1<=999999)))");
CellRangeAddressList addressList = new CellRangeAddressList(0, 1000, 3, 3);
DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
if (workbook instanceof XSSFWorkbook) validation.setShowErrorBox(true);
sheet.addValidationData(validation);
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
workbook.close();
out.close();
}
}