[英]how to copy a drop down list in excel with apache poi?
I copy one cell that contains one drop-down list to another, but the drop-down list is not copied. 我将包含一个下拉列表的一个单元格复制到另一个下拉列表,但不会复制下拉列表。 If I do it on the file excel with ctrl+c and ctrl+v it works and copies the drop down list in the new cell. 如果我使用ctrl + c和ctrl + v在文件excel上执行此操作,它将工作并复制新单元格中的下拉列表。
Is there any way to copy it with Apache Poi? 有没有办法用Apache Poi复制它?
I copy the cell containing the drop-down list, but the result is just the value and not the drop-down list. 我复制包含下拉列表的单元格,但结果只是值而不是下拉列表。
I have one sheet where I have the drop-down list and want copy to another cell and The data (Libro.xls). 我有一张表,我有下拉列表,并希望复制到另一个单元格和数据(Libro.xls)。
I have this methods in the class Excel. 我在Excel类中有这些方法。
package es.fips;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
public class Excel {
private static HSSFWorkbook workbook = null;
private static FileInputStream fis = null;
private static HSSFSheet sheet = null;
public static boolean openExcel(String pathExcel) {
// Cargar la ruta del fichero Excel.
try {
fis = new FileInputStream(pathExcel);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
// Linkeamos el documento excel.
try {
workbook = new HSSFWorkbook(fis);
loadSheet(0);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
private static boolean loadSheet(int numHoja){
try {
// Obtenemos la hoja.
int hojas = workbook.getNumberOfSheets();
if((hojas-1) < numHoja){
throw new Exception("El fichero excel solo contiene "+hojas+" hojas.");
}else{
sheet = workbook.getSheetAt(numHoja);
return true;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static boolean saveChanges(String dirTemp, String name){
FileOutputStream fos = null;
// Crear fichero de salida para el nuevo excel.
try {
fos = new FileOutputStream(dirTemp+"/"+name);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
// Los cambios realizado en la plantilla los guardamos en el nuevo excel.
try {
workbook.write(fos);
fos.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static void closeExcel(){
try {
if (workbook != null) {
workbook.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void copyCell() {
// Get the source / new row.
Row newRow = sheet.getRow(2);// Row number 3.
Row sourceRow = sheet.getRow(2);// Row number 3.
// Grab a copy of the old/new cell
Cell oldCell = sourceRow.getCell(3);// Column D.
Cell newCell = newRow.createCell(5);// Column F.
// Copy STYLE from old cell and apply to new cell.
HSSFCellStyle newCellStyle = workbook.createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
newCell.setCellStyle(newCellStyle);
// If there is a cell comment, copy.
if (newCell.getCellComment() != null) {
newCell.setCellComment(oldCell.getCellComment());
}
// If there is a cell hyperlink, copy.
if (oldCell.getHyperlink() != null) {
newCell.setHyperlink(oldCell.getHyperlink());
}
// Set the cell data TYPE.
newCell.setCellType(oldCell.getCellType());
// Set the cell data value.
switch (oldCell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
newCell.setCellErrorValue(oldCell.getErrorCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
case Cell.CELL_TYPE_NUMERIC:
newCell.setCellValue(oldCell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(oldCell.getStringCellValue());
break;
}
}
}
And my Main class: 而我的主要课程:
package es.fips;
public class Main {
public static void main(String[] args) {
Excel.openExcel("Path/Libro.xls");
Excel.copyCell();
Excel.saveChanges("Path", "New.xls");
Excel.closeExcel();
}
}
And the result (New.xls): Only copy the value of the cell, but not the drop-down list. 结果(New.xls):只复制单元格的值,而不复制下拉列表。
I want to copy the drop-down list, thanks for the future answers. 我想复制下拉列表,感谢未来的答案。
It is related to the poi DataValidation function. 它与poi DataValidation函数有关。
private static boolean equalsRegion(final CellRangeAddressList region1, final CellRangeAddressList region2) {
return equalsSqref(convertSqref(region1), convertSqref(region2));
}
private static boolean equalsSqref(final List<String> sqref1, final List<String> sqref2) {
if(sqref1.size() != sqref2.size())
return false;
Collections.sort(sqref1);
Collections.sort(sqref2);
final int size = sqref1.size();
for(int i = 0; i < size; ++i) {
if(!sqref1.get(i).equals(sqref2.get(i))) {
return false;
}
}
return true;
}
private static List<String> convertSqref(final CellRangeAddressList region) {
List<String> sqref = new ArrayList<String>();
for(CellRangeAddress range : region.getCellRangeAddresses()) {
sqref.add(range.formatAsString());
}
return sqref;
}
private static boolean updateDataValidationRegion(final Sheet sheet, final CellRangeAddressList oldRegion, final CellRangeAddressList newRegion) {
if(sheet instanceof XSSFSheet) {
List<String> oldSqref = convertSqref(oldRegion);
try {
final XSSFSheet xssfSheet = (XSSFSheet) sheet;
Field fWorksheet = XSSFSheet.class.getDeclaredField("worksheet");
fWorksheet.setAccessible(true);
CTWorksheet worksheet = (CTWorksheet) fWorksheet.get(xssfSheet);
CTDataValidations dataValidations = worksheet.getDataValidations();
if(dataValidations == null)
return false;
for(int i = 0; i < dataValidations.getCount(); ++i) {
CTDataValidation dv = dataValidations.getDataValidationArray(i);
@SuppressWarnings("unchecked")
List<String> sqref = new ArrayList<String>(dv.getSqref());
if(equalsSqref(sqref, oldSqref)) {
List<String> newSqref = convertSqref(newRegion);
dv.setSqref(newSqref);
dataValidations.setDataValidationArray(i, dv);
return true;
}
}
return false;
} catch(Exception e) {
throw new RuntimeException("fail update DataValidation's Region.", e);
}
} else if(sheet instanceof HSSFSheet) {
final HSSFSheet hssfSheet = (HSSFSheet) sheet;
try {
Field fWorksheet = HSSFSheet.class.getDeclaredField("_sheet");
fWorksheet.setAccessible(true);
InternalSheet worksheet = (InternalSheet) fWorksheet.get(hssfSheet);
DataValidityTable dvt = worksheet.getOrCreateDataValidityTable();
final AtomicBoolean updated = new AtomicBoolean(false);
org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor visitor = new org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor() {
@Override
public void visitRecord(Record r) {
if (!(r instanceof DVRecord))
return;
final DVRecord dvRecord = (DVRecord) r;
final CellRangeAddressList region = dvRecord.getCellRangeAddress();
if(equalsRegion(region, oldRegion)) {
while(region.countRanges() != 0)
region.remove(0);
for(CellRangeAddress newRange : newRegion.getCellRangeAddresses())
region.addCellRangeAddress(newRange);
updated.set(true);
}
}
};
dvt.visitContainedRecords(visitor);
return updated.get();
} catch(Exception e) {
throw new RuntimeException("fail update DataValidation's Region.", e);
}
}
throw new UnsupportedOperationException("not supported update dava validation's region for type " + sheet.getClass().getName());
}
After called copyCell(), you have to decide which cell ranges for which data validation rule. 在调用copyCell()之后,您必须决定哪个数据范围用于哪个数据验证规则。
for (DataValidation validation : sheet.getDataValidations()) {
CellRangeAddress[] crAddresses = validation.getRegions().getCellRangeAddresses();
CellRangeAddressList addrList = new CellRangeAddressList();
for (CellRangeAddress crAddress : crAddresses)
addrList.addCellRangeAddress(newFirstRow, newFirstColumn, newLastRow, newLastColumn);
updateDataValidationRegion(sheet, validation.getRegions(), addrList);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.