Summary: | HSSFSheet - RuntimeException: Unexpected missing row | ||
---|---|---|---|
Product: | POI | Reporter: | Kamil [Camillo] Soltys <kamil.soltys> |
Component: | HSSF | Assignee: | POI Developers List <dev> |
Status: | RESOLVED DUPLICATE | ||
Severity: | normal | CC: | jonathan.holloway, pedro.t.garcia, sime.essert |
Priority: | P1 | ||
Version: | 3.8-dev | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | Windows Vista | ||
Bug Depends on: | 47245 | ||
Bug Blocks: | |||
Attachments: | Test File with RuntimeException: Unexpected missing row |
Description
Kamil [Camillo] Soltys
2010-05-19 05:30:33 UTC
After resaving in MSExcel of this sample file was the size greater... whatever - the size is not the same like before, but file can be after that with POI processsed. You should probably open a bug with the people who make your spreadsheet writing software. It's putting non row records into the middle of the bit where the row records should live If you want to produce a workaround, you'll need to use hssf.dev.BiffViewer to figure out what those records are that are in the wrong place, then produce a patch to poi to have it handle them coming where they're not supposed to be Thank you for response. It ist possible to configure or learn POI to ignore that non-row-records without patching of POI? Thanks Code changes will be needed. If you do come up with a patch, please do share it! I have tonight analysed the File with BiffViewer. If 'm I right so: - the count of RowRecords in Sheet is 7 (index 6) - at end of CellValues are 4 that are pointed at RowRecord 8 (index 7) and throws RuntimeException Like you said - it is not POI Problem but SAP Businessobject. The Fullclient reporting engine that generates Excel output is bugy. It is not supported by SAP anymore. The Webi reporting engine generates clean XLS and cann be opened by POI. I have fixed it by commenting im HSSFSheet at row 170 this RuntimeException out, so that the missing RowRecord for CellValue will be created. I think it is NOT clean, but in our Case of postprocessing the Excel output form SAP Businessobjects Fullclient Reports does it. POI rocks! mee too. I have this error: Exception in thread "main" java.lang.RuntimeException: Unexpected missing row when some rows already present at org.apache.poi.hssf.usermodel.HSSFSheet.setPropertiesFromSheet(HSSFSheet.java:168) at org.apache.poi.hssf.usermodel.HSSFSheet.<init>(HSSFSheet.java:115) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:299) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:250) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:194) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:329) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:310) at Extraction.main(Extraction.java:93) line cause: wbd = new HSSFWorkbook(istr); I have 2 HSSFWorkbook: wb, wbd. Here is my code: import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.Collator; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Iterator; import java.util.Locale; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFDataFormat; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import Modele.Agent; public class Extraction { public static void main(String[] args) throws ParseException { //VARIABLE POUR LES INFOS DU FICHIER EXCEL String fichierExtract = "C:/Donnees/Aide_Manager/extract_25012012.xls"; String fichierProjection = "C:/Donnees/Aide_Manager/Projection_2012_Eq2.xlsx"; InputStream is, istr,ist; HSSFWorkbook wb, wbd; HSSFSheet sheet, sheetd; HSSFRow row, rowd; HSSFCell cell, celld; String onglet; String semaine_en_string; int n_l_valid = 0; // pour récupérer la ligne de chaque validation int valid = 0; // pour récupérer le nombre de validation HSSFCell valid_recupere = null;// pour récupérer les valeurs des validations java.util.Date datextract; DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); String date_extract; Calendar calendar = Calendar.getInstance(); int validation_ancienne, validation_nouvelle; //VARIABLE POUR OBJET ArrayList<Agent> listAgent = new ArrayList<Agent>(); String prenom_agent = null; //pour récupérer les Agents String ag; int va; String sub; int isub; //TABLEAUX String tab[][] = new String [100][100]; int tabvalidation[][] = new int [100][100]; int onglet_conv; int semaine = 0; try { is = new FileInputStream(fichierExtract); //POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("extract.xls")); //pour ouvrir les fichiers xls wb = new HSSFWorkbook(is); sheet = wb.getSheetAt(0); row = null; cell = null; int n = 0; //int i = 0;//compte le nombre d'agent for (Iterator rowIt = sheet.rowIterator(); rowIt.hasNext();){ row = (HSSFRow) rowIt.next(); Agent a = new Agent(); n++;// pour avoir le numéro de chaque ligne lue if(row.getRowNum() == 6 && row.getCell(0) != null){//pour obtenir la date de l'extract et déterminer sa semaine dans l'année. date_extract = row.getCell(0).getStringCellValue().substring(3,13);//on récupère la date System.out.println("date_extract: "+date_extract); //faire une vérification pour savoir: //si la date du fichier n'est pas trouvée sur istr = new FileInputStream("C:/Donnees/Aide_Manager/date_extract1.xls"); //ce fichier permettra de récupérer les dates pour savoir si un extract à déjà été utilisé. wbd = new HSSFWorkbook(istr); sheetd = wbd.getSheetAt(0); rowd = null; celld = null; //date_extract="24/01/2012"; boolean date_stockee_trouvee = false; int dernLigneTrouvee = 0; for (Iterator r = sheetd.rowIterator(); r.hasNext();){ rowd = (HSSFRow) r.next(); celld = rowd.getCell(0); //System.out.println("lalalalalala"); if(celld != null ){ if(celld.getCellType()==0){ System.out.println("c'est un nombre: "+celld.getNumericCellValue()); }else{ System.out.println("c'est une chaine: "+celld.getStringCellValue()); if(celld.getStringCellValue().equals(date_extract)){// si on trouve que la date_extract est = à la date trouvée dans le fichier System.out.println("DATE TROUVEE Ds le fichier !"); System.out.println("CETTE EXTRACT A DEJA ETE UTILISEE !!"); System.out.println("MERCI D'UTILISER UN AUTRE EXTRACT CONCERNANT UNE AUTRE DATE !"); date_stockee_trouvee=true; } } dernLigneTrouvee = rowd.getCell(0).getRowIndex(); } } dernLigneTrouvee++; System.out.println("dernLigneTrouvee: "+dernLigneTrouvee); //si la date n'est pas trouvée dans le fichier System.out.println("date_stockee_trouvee: "+date_stockee_trouvee); if(date_stockee_trouvee==false){ //retrouver la dernière ligne du fichier pour y ecrire la date System.out.println("retrouver la dernière ligne du fichier: "+dernLigneTrouvee); //pour crée la date ds le fichier //et pour la retrouver et eviter de rajouter la validation d'un extract comportant la même date rowd.setRowNum(dernLigneTrouvee); sheetd.createRow(0); celld = rowd.createCell(0); celld.setCellValue(date_extract); System.out.println("La nouvelle date_extract '"+date_extract+"' a été stocké dans le fichier."); //pour ecrire dans le même fichier FileOutputStream fileOutd = new FileOutputStream("C:/Donnees/Aide_Manager/date_extract1.xls"); wbd.write(fileOutd); fileOutd.close(); // Date actuelle datextract = formatter.parse(date_extract); calendar.setTime(datextract); semaine = calendar.get(Calendar.WEEK_OF_YEAR);//récupérer la semaine dans l'année pour faire la comparaison avec les onglet du fichier de destination //System.out.println(calendar.get(Calendar.WEEK_OF_YEAR)); } } if(row.getCell(0) != null && row.getCell(0).getStringCellValue().startsWith("Agent")){//si les lignes de la colonne 0 ne sont pas null prenom_agent=row.getCell(0).getStringCellValue();//on récupère notre agent //isub = nom_agent.indexOf(","); sub = prenom_agent.substring(prenom_agent.indexOf(",")+1).trim();//récupérer la chaine après la virgule, après l'espace mais sans l'espace à la fin //System.out.println(sub); a.setAgent(sub);//on récupère notre agent dans notre objet //System.out.println(a.getAgent()); //on l'affiche } if(row.getCell(1) != null && row.getCell(1).getStringCellValue().startsWith("Validation")){// si les lignes de la colonne 2 ne sont pas null valid++; //Nombre de validation détecter dans le fichier n_l_valid = n; // on récupère le numéro de ligne de la Validation //System.out.println(nom_agent); n_l_valid--;//on décrémente pour récupérer la validation dans le fichier //valid_recupere=sheet.getRow(n_l_valid).getCell(4);// on récupére la validation dans le fichier //System.out.println("Validation: "+valid_recupere);//on l'affiche a.setValidation((int)sheet.getRow(n_l_valid).getCell(4).getNumericCellValue());//on récupère notre agent dans notre objet sous forme d'entier System.out.println("validation: "+a.getValidation());//on l'affiche } listAgent.add(a); }//fin du for /*for (Agent agt : listAgent){ if(agt.getAgent()!=null) System.out.println("agent: "+agt.getAgent()+"--validation: "+agt.getValidation()); }*/ int k = 0;//pour passer à la colonne suivante for (Agent agt : listAgent){ if(agt.getAgent()!=null){//si l'agent n'est pas null ag=agt.getAgent().toUpperCase();//obtenir L'agent tab[0][k]=ag; //System.out.println("k: "+k); } if(agt.getValidation()!=0){//si la validation n'est pas null va=agt.getValidation();//obtenir la validation tabvalidation[1][k]=va;//assigner les 2 valeurs trouvées k++;//passe à la colonne suivante } } //System.out.println(""); //System.out.println(""); /*for (int d=0; d<tab.length;d++){ if(tab[0][d] != null || tab[1][d]!=null){//si l'une des cellules n'est pas null //afficher l'agent + la validation System.out.println("Agent: "+tab[0][d]+" Validation: "+tab[1][d]); } }*/ int nbfeuille=0; int ligne_trouvee; //version .xls /*InputStream ist = new FileInputStream("C:/Users/LZ2059/Desktop/Projection_2012_Eq2.xls"); //pour ouvrir les fichiers xls de 2007 HSSFWorkbook wb2 = new HSSFWorkbook(ist); HSSFSheet sheet2 = wb2.getSheetAt(0); nbfeuille= wb2.getNumberOfSheets();//retourne le nombre de feuille renseigné HSSFRow row2 = null; HSSFCell cell2 = null; HSSFCellStyle cellStyle = null;*/ //version .xlsx ist = new FileInputStream(fichierProjection); OPCPackage opc=OPCPackage.open(ist);//version .xlsx XSSFWorkbook wb2= new XSSFWorkbook(opc); XSSFSheet sheet2 = wb2.getSheetAt(0);//onglet 0 nbfeuille= wb2.getNumberOfSheets();//retourne le nombre de feuille renseigné XSSFRow row2 = null; XSSFCell cell2 = null; XSSFCellStyle cellStyle = null; XSSFDataFormat fmt = wb2.createDataFormat(); //version .xlsx //pour ouvrir un .xlsx FormulaEvaluator evaluator = wb2.getCreationHelper().createFormulaEvaluator(); evaluator.evaluate(cell2); String prenom_proj; Collator usCollator; System.out.println("wb2.getNumberOfNames(): "+nbfeuille); // il faut définir la feuille qui sera alimenté: //Parcourir les feuilles du document //si la semaine correspond au libellé d'une feuille for (int g=0; g<nbfeuille; g++){//boucle de parcours des onglets sheet2 = wb2.getSheetAt(g); onglet=sheet2.getSheetName();// on récupère le nom de la feuille excel en String if(onglet.startsWith("S")){//si ca commence par "S" //on enleve le "S" semaine_en_string=onglet.substring(1); // on converti le nom de l'onglet en Int onglet_conv = Integer.parseInt(semaine_en_string); System.out.println("onglet: "+onglet_conv); if(onglet_conv == semaine){//si la semaine de l'onglet du doc "extract.xls" //correspond à la semaine de l'année trouver dans le fichier "Projection_2012_Eq2.xls" System.out.println("onglet de la semaine "+onglet_conv+" TROUVEE !"); for (Iterator it = sheet2.rowIterator(); it.hasNext();){//boucle de parcours du fichier de ligne en ligne row2 = (XSSFRow) it.next(); if(row2.getCell(0)!= null && row2.getRowNum() <= 19){// si la ligne est différent de null et inférieur ou égale à la 20ème ligne if(!row2.getCell(0).getStringCellValue().equals("Noms") && !row2.getCell(0).getStringCellValue().equals("EQUIPE") && !row2.getCell(0).getStringCellValue().equals("")){ //on récupère le 1er prénom du fichier Projection prenom_proj=row2.getCell(0).getStringCellValue().toUpperCase(); for (int d=0; d<tab.length;d++){ if(tab[0][d] != null || tab[1][d]!=null){//si l'une des cellules n'est pas null //System.out.println("Tab"+tab[0][d]); //System.out.println("prénom: "+prenom_proj); //Get the Collator for US English and set its strength to PRIMARY usCollator = Collator.getInstance(Locale.FRANCE); usCollator.setStrength(Collator.PRIMARY); if( usCollator.compare(prenom_proj, tab[0][d]) == 0 ){//si le prénom trouvé dans le fichier 'Projection_2012_Eq2.xlsx' correspond au prenom de l'extract Hermes //System.out.println("Strings are equivalent"); System.out.println("Agent: "+tab[0][d]+" Validation: "+tabvalidation[1][d]); //on récupère la ligne du prénom ligne_trouvee= row2.getCell(0).getRowIndex(); ligne_trouvee++;//pour écrire dans la bonne ligne //System.out.println("ligne TROUVEE: "+ligne_trouvee); //on récupère la valeur si présente pour l'additionner cell2 = row2.getCell(8);// colonne(I) validation_ancienne=(int)cell2.getNumericCellValue(); System.out.println("valdation_ancienne"+validation_ancienne); //on additionne validation_nouvelle=validation_ancienne+tabvalidation[1][d]; //on écrit dans la colonne I la validation du prénom trouvé //cell2 = row2.getCell(8);// colonne(I) cell2 = row2.createCell(8); cell2.setCellType(Cell.CELL_TYPE_NUMERIC); cell2.setCellValue(validation_nouvelle); System.out.println("Nouvelle valeur écrite"+validation_nouvelle); //on ré-écrit la formule pour la colonne J cell2 = row2.getCell(9);// colonne(J) cell2 = row2.createCell(9); cell2.setCellFormula("I"+ligne_trouvee+"/B"+ligne_trouvee); //System.out.println("Formule: I"+ligne_trouvee+"/B"+ligne_trouvee); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("#,##0.00")); //cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));//version .xls cell2.setCellStyle(cellStyle); //on ré-écrit la formule pour la colonne K cell2 = row2.getCell(10);// colonne(K) cell2 = row2.createCell(10); cell2.setCellFormula("I"+ligne_trouvee+"/C"+ligne_trouvee); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("0.0%")); cell2.setCellStyle(cellStyle); //on ré-écrit la formule pour la colonne L cell2 = row2.getCell(11);// colonne(L) cell2 = row2.createCell(11); cell2.setCellFormula("J"+ligne_trouvee+"*7"); //System.out.println("Formule: J"+ligne_trouvee+"*7"); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("#,##0.00")); cell2.setCellStyle(cellStyle); ligne_trouvee--;//pour retrouver ma ligne } } } } } } //on réécrit la formule du total colonne I en se fixant à la ligne de total des equipe (20) row2.setRowNum(20); cell2 = row2.createCell(8); String colonneI = "I3:I20"; cell2.setCellFormula("SUM(I3:I20)"); //format EQUIPE de la colonne I cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("#,##0"));//format 1 000 par ex. cell2.setCellStyle(cellStyle); System.out.println("Total Validation refait"); //on réécrit la formule du total colonne J row2.setRowNum(20); //System.out.println("on doit se fixer à la ligne 20: "+row2.getRowNum()); cell2 = row2.createCell(9);//colonne J String resultatParH = "SUM(I3:I20)/SUM(B3:B20)"; cell2.setCellFormula(resultatParH); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("#,##0.00")); cell2.setCellStyle(cellStyle); //on réécrit la formule du total colonne K row2.setRowNum(20); //System.out.println("on doit se fixer à la ligne 20: "+row2.getRowNum()); cell2 = row2.createCell(10);//colonne K String txtransfo = "(SUM(I3:I20)/SUM(C3:C20))/100";//j'ai rajouté /100 pour prendre en compte le % dans l'ecriture du format cell2.setCellFormula(txtransfo); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("0.00%")); cell2.setCellStyle(cellStyle); //on réécrit la formule du total colonne L row2.setRowNum(20); //System.out.println("on doit se fixer à la ligne 20: "+row2.getRowNum()); cell2 = row2.createCell(11);//colonne L String resultatetp = "J21*7"; cell2.setCellFormula(resultatetp); //arrondir à 2 chiffre après la virgule cellStyle = wb2.createCellStyle(); cellStyle.setDataFormat(fmt.getFormat("0.00")); cell2.setCellStyle(cellStyle); } } }//for //pour ecrire dans le même fichier FileOutputStream fileOut = new FileOutputStream("C:/Donnees/Aide_Manager/Projection_2012_Eq2.xlsx"); wb2.write(fileOut); fileOut.close(); } catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /*public void ecrireDansFichier(String monfichierdedestination, String Tableau[][]){ InputStream inp; try { inp = new FileInputStream("workbook.xls");//à remplacer par monfichierdedestination Workbook wb; try { wb = WorkbookFactory.create(inp); Sheet sheet = wb.getSheet("test");//onglet 0 Row row = sheet.getRow(3);//en fonction des personnes Cell cell = row.getCell(8);//colonne 8 (I) if (cell == null) cell = row.createCell(8);//ecrire à la colonne 8 cell.setCellType(Cell.CELL_TYPE_STRING); cell.setCellValue("j'écrit dans la feuille 'test'"); // Write the output to a file FileOutputStream fileOut = new FileOutputStream("workbook.xls"); wb.write(fileOut); fileOut.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }*/ } Please attach the input file, without it we cannot ru your code to reproduce the problem. Yegor (In reply to comment #6) > mee too. > I have this error: > Exception in thread "main" java.lang.RuntimeException: Unexpected missing row > when some rows already present > at > I have added one problematic file on https://issues.apache.org/bugzilla/show_bug.cgi?id=47245 |