Apache POI event API Mettre à jour la feuille Excel existante

J'ai un grand file excel avec plusieurs feuilles de calcul.
Je veux traiter une seule feuille dans le file … Lire la valeur à partir de deux colonnes et mettre à jour deux colonnes.

À l'aide de ce code, je peux lire datatables à partir de la feuille. Mais impossible de comprendre, comment save la sortie.

public class ExcelFunctions { private class ExcelData implements SheetContentsHandler { private Record rec ; public void startRow(int rowNum) { rec = new Record(); output.put("R"+rowNum, rec); } public void endRow(int rowNum) { } public void cell(Ssortingng cellReference, Ssortingng formattedValue, XSSFComment comment) { int thisCol = (new CellReference(cellReference)).getCol(); if(thisCol==7){ try { rec.setK1(formattedValue); } catch (Exception e) { } } if(thisCol==8){ try { rec.setK2(formattedValue); } catch (Exception e) { } } if(thisCol == 27){ Ssortingng key = rec.full_key(); System.out.println(key); ///////Process Matched Key...get Data //////Set value to column 27 } if(thisCol == 28){ Ssortingng key = rec.full_key(); System.out.println(key); ///////Process Matched Key...get Data //////Set value to column 28 } } public void headerFooter(Ssortingng text, boolean isHeader, Ssortingng tagName) { } } /////////////////////////////////////// private final OPCPackage xlsxPackage; private final Map<Ssortingng, Record> output; public ExcelFunctions(OPCPackage pkg, Map<Ssortingng, Record> output) { this.xlsxPackage = pkg; this.output = output; } public void processSheet( StylesTable styles, ReadOnlySharedSsortingngsTable ssortingngs, SheetContentsHandler sheetHandler, InputStream sheetInputStream) throws IOException, ParserConfigurationException, SAXException { DataFormatter formatter = new DataFormatter(); InputSource sheetSource = new InputSource(sheetInputStream); try { XMLReader sheetParser = SAXHelper.newXMLReader(); ContentHandler handler = new XSSFSheetXMLHandler( styles, null, ssortingngs, sheetHandler, formatter, false); sheetParser.setContentHandler(handler); sheetParser.parse(sheetSource); } catch(ParserConfigurationException e) { throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); } } public void process() throws IOException, OpenXML4JException, ParserConfigurationException, SAXException { ReadOnlySharedSsortingngsTable ssortingngs = new ReadOnlySharedSsortingngsTable(this.xlsxPackage); XSSFReader xssfReader = new XSSFReader(this.xlsxPackage); StylesTable styles = xssfReader.getStylesTable(); XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); boolean found = false; while (iter.hasNext() && !found) { InputStream stream = iter.next(); Ssortingng sheetName = iter.getSheetName(); if(sheetName.equals("All Notes") ){ processSheet(styles, ssortingngs, new ExcelData(), stream); found = true; } stream.close(); } } @SuppressWarnings("unused") public static void main(Ssortingng[] args) throws Exception { File xlsxFile = new File("C:\\Users\\admin\\Downloads\\Unique Name Macro\\big.xlsm"); if (!xlsxFile.exists()) { System.err.println("Not found or not a file: " + xlsxFile.getPath()); return; } // The package open is instantaneous, as it should be. OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ_WRITE); Map<Ssortingng, Record> output = new HashMap<Ssortingng, Record>(); ExcelFunctions xlFunctions = new ExcelFunctions(p, output); xlFunctions.process(); p.close(); if (output != null){ for(Record rec : output.values()){ System.out.println(rec.full_key()); } } } } 

Le file est très large et je ne souhaite qu'utiliser l'API événementielle.
J'ai testé avec succès l'utilisation de ce code.
Mais cela charge le file entier en memory (provoquant une panne de l'application) … Bien que je n'ai besoin que d'éditer une feuille.

  public static void saveToExcel(Ssortingng ofn, Map<Ssortingng, Record> data) { FileInputStream infile; try { infile = new FileInputStream(new File("C:\\Users\\admin\\Downloads\\Unique Name Macro\\big.xlsm")); XSSFWorkbook workbook = new XSSFWorkbook (infile); XSSFSheet sheet = workbook.getSheet("All Notes"); for(Record rec : output.values()){ Row dataRow = rec.getRow(rev.getRownum-1); setCellValue(dataRow, 26, "SomeValue"); setCellValue(dataRow, 27, "SomeValue"); } FileOutputStream out = new FileOutputStream(new File(ofn)); workbook.write(out); infile.close(); out.close(); workbook.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void setCellValue(Row row,int col, Ssortingng value){ Cell c0 = row.getCell(col); if (c0 == null){ c0 = row.createCell(col); } c0.setCellValue(value); } 

Je ne pense pas qu'il y ait quoi de quoi que ce soit dans POI hors de la boîte, ce qui permet de le faire.

Par conséquent, vous pourriez être mieux de le faire en décompressant le file XLSX / XLSM (ils sont en fait un tas de files xml à l'intérieur d'un zip) et en lisant les files xml en tant que files text ou avec un parsingur XML normal afin que vous puissiez facilement écrivez le file modifié à nouveau pour produire à nouveau le file XLSX / XLSM.