2017-11-24 2 views
0

Ich brauche die Drop-down (Filter) in einem geschützten XLS Blatt zu ermöglichen. Ich habe unten Code geschrieben und auch das XLS angehängt, das daraus generiert wird. Wenn Sie das Excel öffnen, sehen Sie die Dropdown-Filter, aber es wird nicht für die Auswahl aktiviert.Aktivieren in xls nach unten fallen, sobald Blatt geschützt ist

Einschränkungen, die ich habe sind: Ich muss den Schutz des Blattes auf und ich brauche diese Funktion im XLS-Format nur Datei (nicht XLSX).

Danke für Ihre Hilfe,

Shashank

String excelFileName = "C:\\Users\\Admin\\Desktop\\GN_Files\\Test.xls";//name of excel file 
     String sheetName = "Sheet1";//name of sheet 
     HSSFWorkbook wb = new HSSFWorkbook(); 

     HSSFSheet sheet = wb.createSheet(sheetName) ; 
     //sheet.protectSheet(""); 
     //iterating r number of rows 
     CellStyle style=wb.createCellStyle(); 
     style.setLocked(false); 
     sheet.setAutoFilter(CellRangeAddress.valueOf("A1:C3")); 
     for (int r=0;r < 3; r++) 
     { 
       HSSFRow row = sheet.createRow(r); 

       //iterating c number of columns 

       for (int c=0;c < 3; c++) 
       { 
        if(r==1){ 
        HSSFCell cell = row.createCell(c); 
        cell.setCellValue(1); 
        //cell.setCellStyle(style); 
        } 
        if(r==2){ 
          HSSFCell cell = row.createCell(c); 
          cell.setCellValue(2); 
          //cell.setCellStyle(style); 
          } 
        if(r==0){ 
          HSSFCell cell = row.createCell(c); 
          cell.setCellValue(0); 
          cell.setCellStyle(style); 
          } 
       } 

     } 

     sheet.protectSheet(""); 
     FileOutputStream fileOut = new FileOutputStream(excelFileName); 
     //write this workbook to an Outputstream. 
     wb.write(fileOut); 
     fileOut.flush(); 
     fileOut.close(); 
     wb.close(); 
     System.out.println("done-----"); 
+0

** Was ** unter Code? – Jeeped

+0

Das ist nicht [tag: vba]. Sieht so aus [tag: poi]. – Jeeped

+0

Nur geteilt, bitte überprüfen Sie. –

Antwort

0

Nach OpenOffice BIFF8 documentation ist die SHEETPROTECTION ein BIFF Datensatz in der Sheet Substream. Also müssen wir diesen Datensatz dort einfügen.

Unfortunatelly tut apache poi dies nicht unterstützt. Also können wir das nur selbst machen. Ich folgendes Beispiel bekomme ich die InternalSheet und die Datensätze in es mit Reflexion. Dann stelle ich eine neue Klasse SheetProtectionRecord zur Verfügung, die nach OpenOffice BIFF8-Dokumentation erstellt wird. Die Bytes 19 und 20 der byte[] data sind diejenigen, die die Option flags sind.

import java.io.FileOutputStream; 

import org.apache.poi.hssf.usermodel.*; 

import org.apache.poi.ss.util.CellRangeAddress; 

import org.apache.poi.hssf.record.RecordBase; 
import org.apache.poi.hssf.record.StandardRecord; 
import org.apache.poi.hssf.model.InternalSheet; 
import org.apache.poi.util.LittleEndianOutput; 

import java.lang.reflect.Field; 

import java.util.List; 

public class CreateExcelHSSFProtectedSheet { 

public static void main(String[] args) throws Exception { 

    HSSFWorkbook workbook = new HSSFWorkbook(); 
    HSSFSheet sheet = workbook.createSheet(); 

    sheet.setAutoFilter(CellRangeAddress.valueOf("A1:C3")); 
    HSSFRow row = sheet.createRow(0); 
    for (int c = 0; c < 3; c++) { 
    row.createCell(c).setCellValue("Col " + (c+1)); 
    } 

    for (int r = 1; r < 4; r++) { 
    row = sheet.createRow(r); 
    for (int c = 0; c < 3; c++) { 
    row.createCell(c).setCellValue(r * (c+1)); 
    } 
    } 

    sheet.protectSheet(""); 
    Field _sheet = HSSFSheet.class.getDeclaredField("_sheet"); 
    _sheet.setAccessible(true); 
    InternalSheet internalsheet = (InternalSheet)_sheet.get(sheet); 

    Field _records = InternalSheet.class.getDeclaredField("_records"); 
    _records.setAccessible(true); 
    @SuppressWarnings("unchecked") 
    List<RecordBase> records = (List<RecordBase>)_records.get(internalsheet); 

    SheetProtectionRecord sheetprotection = new SheetProtectionRecord(); 
    sheetprotection.lockAutoFilter(false); 
    sheetprotection.lockInsertRows(false); 
    sheetprotection.lockInsertHyperlinks(false); 

    records.add(records.size() - 1, sheetprotection); 

/* 
    for (RecordBase r : internalsheet.getRecords()) { 
    System.out.println(r); 
    } 
*/ 

    workbook.write(new FileOutputStream("CreateExcelHSSFProtectedSheet.xls")); 
    workbook.close(); 

} 

static class SheetProtectionRecord extends StandardRecord { 

    //see https://www.openoffice.org/sc/excelfileformat.pdf#%5B%7B%22num%22%3A635%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C85.6%2C771.1%2C0%5D 

    byte[] data = new byte[]{(byte)0x67, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0x00, (byte)0x44, 0x00, 0x00}; 

    public int getDataSize() { 
    return 23; 
    } 

    public short getSid() { 
    return (short)0x0867; 
    } 

    void lockAutoFilter(boolean lock) { 
    if(lock) data[20] &= 0xEF; 
    else data[20] |= 0x10; 
    } 

    void lockSelectLockedCells(boolean lock) { 
    if(lock) data[20] &= 0xFB; 
    else data[20] |= 0x04; 
    } 

    void lockSelectUnLockedCells(boolean lock) { 
    if(lock) data[20] &= 0xBF; 
    else data[20] |= 0x40; 
    } 

    void lockInsertRows(boolean lock) { 
    if(lock) data[19] &= 0xBF; 
    else data[19] |= 0x40; 
    } 

    void lockInsertHyperlinks(boolean lock) { 
    if(lock) data[19] &= 0x7F; 
    else data[19] |= 0x80; 
    } 
    //further methods .... 

    public void serialize(LittleEndianOutput out) { 
    out.write(data); 
    } 
} 

} 
+0

Vielen Dank @Axel. Das löst meine Frage. Vielen Dank für die Hilfe. –

+0

@Shashank Pandey: Froh, wenn ich dir geholfen habe. Bitte lesen Sie [Hilfe-Center> Fragen] (https://stackoverflow.com/help/asking) -> [Was soll ich tun, wenn jemand meine Frage beantwortet?] (Https://stackoverflow.com/help/someone-answers) . –

+0

Nur eine kleine Abfrage, gibt es eine andere Möglichkeit, einige Zellen zu sperren und jede andere Zelle/Zeile zum Bearbeiten geöffnet zu lassen. Mir ist bewusst, dass wir das Blatt zuerst schützen müssen und dann einen Stil erstellen müssen, der setLocked (false) hat. Egal, welche Zelle wir bearbeiten müssen, wir legen diese als Stil fest. –

Verwandte Themen