Excel formatting with Java Apache POI -


i have excel file in following format:

input format

i restructure format , have outputted in following format:

output format

the sections repeating , can appear in order have either format. 'check' column merged across rows shown in image.

how can achieve this?

i used guava's table data structure save reinventing wheel

a few caveats;

  • there may mathematical trick matrices or pivot tables or functional programming may same job less code.
  • i'm not sure if i'm using latest , greatest poi classes this
  • i have gone brute force , many data iterations should easy follow.
  • i've assumed practical identify ranges of cells define data (abc, xyz, etc.)
  • i guessed first row , column of merged area contain actual value (i don't know if case)
  • the code optimized final variables etc.
  import com.google.common.collect.hashbasedtable; import com.google.common.collect.table; import java.io.file; import java.io.fileinputstream; import java.io.ioexception; import org.apache.poi.hssf.usermodel.hssfsheet; import org.apache.poi.hssf.usermodel.hssfworkbook; import org.apache.poi.ss.usermodel.cell; import org.apache.poi.ss.usermodel.row; import org.apache.poi.ss.usermodel.sheet; import org.apache.poi.ss.util.cellrangeaddress;  public class excelformatting {      public static void main(string[] args) throws ioexception {         fileinputstream file = new fileinputstream(new file("data.xls"));         hssfworkbook workbook = new hssfworkbook(file);         hssfsheet sheet = workbook.getsheetat(0);         // abc - range a3:f7 in data.xls         table<integer, integer, string> abc = getvalues(sheet, 2, 0, 6, 5);         //displaytable(abc);         // xyz - range a11:e14 in data.xls         table<integer, integer, string> xyz = getvalues(sheet, 10, 0, 13, 4);         //displaytable(xyz);          table<integer, integer, string> results = hashbasedtable.create();         // headers         results.put(0, 0, "name");         results.put(0, 1, "section");         results.put(0, 2, "check");         results.put(0, 3, "cat");         results.put(0, 4, "value");         // process abc table         results.putall(transform(abc, "abc", results.rowmap().size()));         // process xyz table                 results.putall(transform(xyz, "xyz", results.rowmap().size()));         displaytable(results);     }       private static table<integer, integer, string> transform(table<integer, integer, string> table, string section, int offset) {         table<integer, integer, string> results = hashbasedtable.create();         int maxrows = table.rowmap().size();         int maxcols = table.columnmap().size();         // first col name         string name;         // second col check         string check;         string cata, catb, catc, catd = null;         // offset added table putall doesn't overlap data rather append         int outputrow = 0 + offset;         (int r = 0; r < maxrows; r++) {             name = table.get(r, 0);             check = table.get(r, 1);             if (check == null) {                 check = "";             }             cata = table.get(r, 2);             catb = table.get(r, 3);             catc = table.get(r, 4);             if (maxcols == 6) {                 catd = table.get(r, 5);             }             if (cata != null) {                 results = addrow(results, outputrow, name, section, check, "a", cata);                 outputrow++;             }             if (catb != null) {                 results = addrow(results, outputrow, name, section, check, "b", catb);                 outputrow++;             }             if (catc != null) {                 results = addrow(results, outputrow, name, section, check, "c", catc);                 outputrow++;             }             if (catd != null) {                 results = addrow(results, outputrow, name, section, check, "d", catd);                 outputrow++;             }         }         return results;     }      private static table<integer, integer, string> addrow(table<integer, integer, string> table, int row, string name, string section, string check, string category, string value) {         table.put(row, 0, name);         table.put(row, 1, section);         table.put(row, 2, check);         table.put(row, 3, category);         table.put(row, 4, value);         return table;     }      // convert "merged" data normal populated cells     private static table<integer, integer, string> getvalues(sheet sheet, int minrow, int mincol, int maxrow, int maxcol) {         table<integer, integer, string> table = hashbasedtable.create();         string result;         row row;         cell col;         int r = minrow;         int c;         while (r <= maxrow) {             row = sheet.getrow(r);             c = mincol;             while (c <= maxcol) {                 col = row.getcell(c);                 result = getvalue(sheet, row, col);                 if (result != null) {                     table.put(r - minrow, c - mincol, result);                 }                 c++;             }             r++;         }         return table;     }      private static string getvalue(sheet sheet, row row, cell cell) {         string result = getcellvalue(cell);         if (result == null) {             result = getmergedareavalue(sheet, row.getrownum(), cell.getcolumnindex());         }         return result;     }      private static string getcellvalue(cell cell) {         string result = null;         if (cell.cell_type_string == cell.getcelltype()) {             result = cell.getstringcellvalue();         }         if (cell.cell_type_numeric == cell.getcelltype()) {             result = cell.getnumericcellvalue() + "";         }         return result;     }      private static string getmergedareavalue(sheet sheet, int row, int col) {         int mergedareas = sheet.getnummergedregions();         cellrangeaddress mergearea;         (int = 0; < mergedareas; i++) {             mergearea = sheet.getmergedregion(i);             if (mergearea.isinrange(row, col)) {                 return getcellvalue(                         sheet.getrow(mergearea.getfirstrow())                         .getcell(mergearea.getfirstcolumn()));             }         }         return null;     }      private static void displaytable(table<integer, integer, string> table) {         int maxrows = table.rowmap().size();         int maxcols = table.columnmap().size();         stringbuilder sb = new stringbuilder();         string val;         (int r = 0; r < maxrows; r++) {             (int c = 0; c < maxcols; c++) {                 val = table.get(r, c);                 if (val != null) {                     sb.append(val);                 }                 sb.append("\t\t");             }             sb.append('\n');         }         system.out.println(sb.tostring());     }   }  

this should result in following output:

 name    sect    check   cat     value        qqq     abc                   1.0      qqq     abc             d       5.0      www     abc     x       b       2.0      www     abc     x       d       5.0      eee     abc     x       c       3.0      eee     abc     x       c       4.0      rrr     abc             d       6.0      qqq     xyz                   1.0      qqq     xyz             c       4.0      www     xyz     x       b       2.0      www     xyz     x       c       4.0      www     xyz     x       b       3.0      www     xyz     x       c       4.0      eee     xyz     x       c       4.0  

Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -