Data validation fails when copy pasting data in excel made through apache poi

后端 未结 1 1502
既然无缘
既然无缘 2021-01-26 06:49

I am making one .xls file using apache poi. I\'m including some data validations also as shown.

ObservableList objectstatusList = UpgradeWorkBench.         


        
相关标签:
1条回答
  • 2021-01-26 07:28

    Since apache poi cannot create macros, the only way is to have a template with the needed macro and creating the result from that template.

    Example:

    Have a template.xls with a worksheet Sheet1 and the macro from http://spreadsheetpage.com/index.php/tip/ensuring_that_data_validation_is_not_deleted/ located in the code module for that worksheet.

    Edit 2020-09-03: The above link is dead now. But see https://superuser.com/questions/870926/restrict-paste-into-dropdown-cells-in-excel. There the used name is "DataValidationRange" instead of "ValidationRange". This would must be considered.

    Then you could use following code:

    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.*;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    
    import org.apache.poi.ss.usermodel.DataValidation.ErrorStyle;
    
    import org.apache.poi.hssf.usermodel.*;
    
    import java.io.*;
    
    class ReadAndWriteFromTemplateWithMacro {
    
     public static void main(String[] args) {
      try {
    
       String templateName = "template.xls";
       String resultName = "result.xls";
     
       String sheetName = "Sheet1";
     
       String[] strStatus = new String[]{"on", "off", "maybe"};
    
       FileInputStream template = new FileInputStream(templateName);
       Workbook wb = WorkbookFactory.create(template);   
       Sheet sheet = wb.getSheet(sheetName);
    
       if (sheet instanceof HSSFSheet) {
    
        CellRangeAddressList addressListStatus = new CellRangeAddressList(0, 65535, 9, 9);  
        DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(strStatus);
        DataValidation dataValidation = new HSSFDataValidation(addressListStatus, dvConstraint);
        dataValidation.setSuppressDropDownArrow(false);
        dataValidation.setErrorStyle(ErrorStyle.STOP);
    
        sheet.addValidationData(dataValidation);
    
        //create a named range for the data validation as described in http://spreadsheetpage.com/index.php/tip/ensuring_that_data_validation_is_not_deleted/
        Name name =  wb.createName();
        name.setNameName("ValidationRange");
        String reference = addressListStatus.getCellRangeAddress(0).formatAsString(sheetName, true);
        name.setRefersToFormula(reference);
    
       }
    
       FileOutputStream output = new FileOutputStream(resultName);
       wb.write(output);
       wb.close();
    
      } catch (InvalidFormatException ifex) {
      } catch (FileNotFoundException fnfex) {
      } catch (IOException ioex) {
      }
     }
    }
    

    Now the result.xls will contain that macro also. If macros are enabled, then this macro will prevent destroy data valitation by pasting over.

    0 讨论(0)
提交回复
热议问题