将定义名称从/xl/workbook.xml(或Excel文件)文件复制到新的Excel文件

时间:2019-04-16 11:21:23

标签: java excel apache-poi

我有一个Excel文件,其中包含列表列,并且此列表数据是从另一个参考表中读取的。因此,我在工作簿上创建了这样的“名称”单元。

private void addListReferenceToHiddenSheet(String key,String[] vallist){
    int initialRowNumber = refCellCount;
    Name name = sxssfWorkbook.getName(getNamedListName(key));
    if(name == null) {
        for (String val : vallist) {
            Row row = listRefSheet.createRow(refCellCount);
            Cell celll = row.createCell(0);
            celll.setCellValue(val);
            refCellCount++;
        }
        Name namedCell = sxssfWorkbook.createName();
        namedCell.setNameName(getNamedListName(key));
        String reference = LIST_REFERENCE_SHEET_NAME + "!$A$" + (initialRowNumber + 1) + ":$A$" + refCellCount + "";
        namedCell.setRefersToFormula(reference);
    }
}

然后将其放在这样的datavalidation上:

   pushListToReferenceSheet(key,vallist);
                /*Adding reference from hidden sheet and validation*/
                dvc = dvHelper.createFormulaListConstraint(getNamedListName(key));
                dv = dvHelper.createValidation(dvc, listConstraintMap.get(key));  

但是我想将此工作簿复制到另一个。是的,它可能基于SXSSF事件。但这事件只是这样阅读。

public void processSheet(StylesTable styles,
                         ReadOnlySharedStringsTable strings, InputStream sheetInputStream)
        throws IOException, ParserConfigurationException, SAXException {
    SheetModel sheetModel = new SheetModel();
    sheetModel.setNumberOfColumns(0);
    sheetModel.setNumberOfRows(0);
    long startTime = System.currentTimeMillis();
    InputSource sheetSource = new InputSource(sheetInputStream);
    SAXParserFactory saxFactory = SAXParserFactory.newInstance();
    SAXParser saxParser = saxFactory.newSAXParser();
    XMLReader sheetParser = saxParser.getXMLReader();
    ContentHandler handler = new XSSFSheetEventHandler(styles, strings,
            this.minColumns,  sheetModel);
    sheetParser.setContentHandler(handler);
    sheetParser.parse(sheetSource);
    sheetModel.setTimeToProcess(System.currentTimeMillis() - startTime);
    System.out.println("Number Of Rows : "+ sheetModel.getNumberOfRows());
    System.out.println("Time to process : "+ sheetModel.getTimeToProcess());
}

这只是迭代工作表事件,但工作簿包含一些 definedNames ,它们位于 /xl/workbook.xml

<definedNames><definedName name="LIST___CURRENCY">LIST_REFERENCE!$A$1:$A$105</definedName><definedName name="LIST_Test_List">LIST_REFERENCE!$A$106:$A$157</definedName><definedName name="LIST_HaulageModeOfTransport">LIST_REFERENCE!$A$158:$A$162</definedName><definedName name="_xlnm._FilterDatabase" localSheetId="2" hidden="true">TRYRTJV_11_OCEAN_FREIGHTS!$A$2:$AD$57</definedName><definedName name="_xlnm._FilterDatabase" localSheetId="3" hidden="true">'REOCEAN_NOV-14_2'!$A$2:$AS$180</definedName></definedNames></workbook>

我没有获得如何读取新工作簿或excel文件中的定义名称的信息。我通过分别阅读 /xl/workbook.xml 来做到这一点。将定义名称从一个excel克隆到另一个excel的这种正确方法吗?

private void readAndPopulateWorkbookData() throws IOException, XMLStreamException {

        PackagePart workbookpart = xlsxPkg.getPartsByName(Pattern.compile("/xl/workbook.xml")).get(0);

        XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(workbookpart.getInputStream());

        boolean isInDefinedName = false;
        String definedNameName = "";
        StringBuffer definedNameFormula = new StringBuffer();

        while(reader.hasNext()){
            XMLEvent event = (XMLEvent)reader.next();

            if(event.isStartElement()) {
                StartElement startElement = (StartElement)event;
                QName startElementName = startElement.getName();
                if (startElementName.getLocalPart().equalsIgnoreCase("definedName")) {
                    Attribute attribute = startElement.getAttributeByName(new QName("name"));
                    definedNameName = attribute.getValue();
                    isInDefinedName = true;
                }
            } else if(event.isCharacters() && isInDefinedName) {
                definedNameFormula.append(((Characters)event).getData());
            } else if(event.isEndElement()) {
                EndElement endElement = (EndElement)event;
                QName endElementName = endElement.getName();
                if(endElementName.getLocalPart().equalsIgnoreCase("definedName")) {
                    if(!definedNameName.equalsIgnoreCase("_xlnm._FilterDatabase")) {
                        Name name = outWorkbook.createName();
                        name.setNameName(definedNameName);
                        name.setRefersToFormula(definedNameFormula.toString());
                    }
                    definedNameFormula = new StringBuffer();
                    isInDefinedName = false;
                }
            }

        }
    }

0 个答案:

没有答案