Advertisement
eriezelagera

Create Excel - Creating Excel from template

Jun 28th, 2014
9,960
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.25 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. import org.apache.poi.xssf.usermodel.*;
  5.  
  6. /**
  7.  * Process all data that will be written to the Excel file.
  8.  * The process starts from reading the template Excel files. <br />
  9.  * This will process the replacement of <b>placeholders</b> from the template file.
  10.  * After the process from template, the Excel file will be written to the specified <b>save path</b>. <br /> <br />
  11.  * <br />
  12.  * <i>
  13.  * Version history: <br />
  14.  * <ul>
  15.  *  <li> Version 1.0 - This has to be the simplest solution, but cell style was the problem. <br />
  16.  *  <li> Version 1.5 - No methods added, just some logic. Cell style problem was fixed,
  17.  *               but doesn't support the multiple detail placeholder. <br />
  18.  *  <li>Version 2.0 - This version supports the detail placeholder, which works almost the same as the JasperReports. <br />
  19.  *               But the current version only supports fixed column size, which means you can't exceed to your <br />
  20.  *               template's number of columns, but row is capable of dynamic count. Methods were added to support <br />
  21.  *               the new placeholder. Moved the old logic to the bottom most this class. <br />
  22.  *               See Detail Placeholder sample @ http://pastebin.com/ZMLLGAMp, <br />
  23.  *               and https://www.dropbox.com/s/kiluqafq8ofmxo8/template.xlsx for sample template file.
  24.  * </ul>
  25.  * </i>
  26.  * <br />
  27.  * Note: <i> Please see the JXLSUtil.java @ http://pastebin.com/Rf4FW9ir, this was for the mergeExcelFiles() method.</i> <br />
  28.  * <br />
  29.  * If you have questions or feedback, please don't hesitate to contact me. This will help us and others a lot!
  30.  * Contact me at <i>erieze.lagera@gmail.com</i>
  31.  *
  32.  * @author Erieze Lagera
  33.  */
  34. public class CreateExcel {
  35.  
  36.     /**
  37.      * Path of the template Excel file.
  38.      */
  39.     private final String file_path;
  40.     /**
  41.      * Sheet index of your template.
  42.      */
  43.     private final int sheet_index;
  44.     /**
  45.      * Path for the resulting Excel file.
  46.      */
  47.     private final String save_path;
  48.     /**
  49.      * Sheet name for the resulting Excel workbook.
  50.      */
  51.     private final String sheet_name;
  52.     /**
  53.      * Contains the placeholders together with their value. <br />
  54.      * <i> Note that the placeholder from the template should starts
  55.      * with dollar sign (<b>$</b>). But dollar sign when putting placeholder
  56.      * in HashMap is not necessary.
  57.      */
  58.     private final Map<String, Object> placeholders;
  59.    
  60.     /**
  61.      * Create an Excel file that will contains the process data.
  62.      * You must have the template Excel file before invoking this method,
  63.      * because this is an dependent processing of Excel file. This needs a template file
  64.      * to create a resulting Excel file.<br /> <br />
  65.      * <i>
  66.      * Note: If save path is null or empty, it will be moved to your <b>Desktop</b> directory.
  67.      * And for file path, null or empty value will be handled by the IOException. <br /> <br />
  68.      * Also the placeholder from the template should starts with dollar sign (<b>$</b>),
  69.      * but not necessary when putting in the Hashmap. <br />
  70.      * Ex. map.put("replaceMe", "Hello");
  71.      * </i>
  72.      * @param file_path Path of the template Excel file
  73.      * @param sheet_index Sheet index of your template
  74.      * @param save_path Path for the resulting Excel file
  75.      * @param sheet_name Sheet name for the resulting Excel workbook
  76.      * @param placeholders Contains the placeholders together with their value.
  77.      */
  78.     public CreateExcel(String file_path, int sheet_index, String save_path, String sheet_name, Map<String, Object> placeholders) {
  79.         this.file_path = file_path;
  80.         this.sheet_index = sheet_index;
  81.         this.save_path = checkSavePath(save_path);
  82.         this.sheet_name = sheet_name;
  83.         this.placeholders = placeholders;
  84.     }
  85.    
  86.     /**
  87.      * Process the creation of the Excel report.
  88.      * @return True if no error occurred during process, otherwise false.
  89.      * @since 1.0
  90.      */
  91.     public boolean execute() {
  92.         try (FileInputStream file = new FileInputStream(new File(file_path))) {
  93.             // Load the template file
  94.             final XSSFWorkbook wb = new XSSFWorkbook(file);
  95.             XSSFSheet sheet = wb.getSheetAt(sheet_index);
  96.             XSSFRow row;
  97.             XSSFCell cell;
  98.             // For resulting Excel file
  99.             XSSFWorkbook wb_new = new XSSFWorkbook();
  100.            
  101.             int row_index = 0;
  102.             int cell_index = 0;
  103.             String cell_str = "";
  104.            
  105.             /*** New: Cell index of the detail placeholder ***/
  106.             int temp_cell_index = 0;
  107.            
  108.             /*** New: User must place #end to tell the program that it is the last row ***/
  109.             // Get row until it reaches the #end
  110.             while (true) {
  111.                 row = sheet.getRow(row_index);
  112.                
  113.                 if (row == null) {
  114.                     row = sheet.createRow(row_index++);
  115.                 }
  116.                
  117.                 // We only support fixed column length and expanding row.
  118.                 for (cell_index = 0; cell_index < row.getPhysicalNumberOfCells(); cell_index++) {
  119.                     cell = row.getCell(cell_index);
  120.                     cell_str = cell.toString();
  121.                    
  122.                     if (isPlaceholder(cell_str)) {
  123.                         cell.setCellValue(getValue(cell_str));
  124.                     }
  125.                     else if (isDetailPlaceholder(cell_str)) {
  126.                         /*
  127.                          * Replace the detail placeholder with anything you want,
  128.                          * for now let's replace it with blank.
  129.                          */
  130.                         cell.setCellValue("");
  131.                        
  132.                         /*
  133.                          * This will give a free row for the detail placeholder,
  134.                          * moving the existing rows based on detail row count.
  135.                          */
  136.                         int detail_count = getValueArr(cell_str).size();
  137.                         sheet.shiftRows(row_index, row_index + detail_count, detail_count);
  138.                        
  139.                         temp_cell_index = cell_index;
  140.                         for (ArrayList<String> valuesArr : getValueArr(cell_str)) {
  141.                             row = sheet.createRow(row_index++);
  142.                             for (String value : valuesArr) {
  143.                                 cell = row.createCell(cell_index++);
  144.                                 cell.setCellValue(value);
  145.                             }
  146.                             cell_index = temp_cell_index;
  147.                         }
  148.                     }
  149.                     // To check if next row is the end
  150.                     cell_str = sheet.getRow(row_index).getCell(0).toString();
  151.                 }
  152.                 // End the iteration
  153.                 if (isEndingCell(cell_str)) {
  154.                     /*
  155.                      * Replace the ending cell placeholder with anything you want,
  156.                      * for now let's replace it with blank.
  157.                      */
  158.                     row.getCell(0).setCellValue("");
  159.                     break;
  160.                 }
  161.                 row_index++;
  162.             }
  163.            
  164.             wb_new = JXLSUtil.mergeExcelFiles(wb_new, wb, sheet_name, 0);
  165.             file.close();
  166.             return doSaveExcelFile(wb_new);
  167.         } catch (IOException e) {
  168.             System.out.println("[ERROR] " + e.getLocalizedMessage());
  169.             return false;
  170.         } catch (Exception e ) {
  171.             e.printStackTrace();
  172.             System.exit(0);
  173.             return false;
  174.         }
  175.     }
  176.    
  177.     /**
  178.      * Checks if the cell is a placeholder.
  179.      * A placeholder always starts with a <i>dollar sign (<b>$</b>)</i>.
  180.      * @param cell A cell in instance of String
  181.      * @return True if the cell is a placeholder
  182.      * @since 1.0
  183.      */
  184.     private boolean isPlaceholder(String cell) {
  185.         return !cell.isEmpty() && cell.charAt(0) == '$';
  186.     }
  187.    
  188.     /**
  189.      * Check if the cell is a detail placeholder.
  190.      * A detail placeholder always starts with <i>percent sign (<b>%</b>)</i>.
  191.      * @param cell A cell in instance of String
  192.      * @return True if the cell is a detail placeholder
  193.      * @since 2.0
  194.      */
  195.     private boolean isDetailPlaceholder(String cell) {
  196.         return !cell.isEmpty() && cell.charAt(0) == '%';
  197.     }
  198.    
  199.     /**
  200.      * Check if the cell is the ending cell (<b>#end</b>).
  201.      * @param cell A cell in instance of String
  202.      * @return True if the cell is the ending cell
  203.      * @since 2.0
  204.      */
  205.     private boolean isEndingCell(String cell) {
  206.         return cell.equalsIgnoreCase("#end");
  207.     }
  208.    
  209.     /**
  210.      * Get the value from the Hashmap by key.
  211.      * The <b>key</b> is the placeholder from your template Excel file.
  212.      * @param cell A cell in instance of String
  213.      * @return The specified value for the specified placeholder
  214.      * @since 1.0
  215.      */
  216.     private String getValue(String cell) {
  217.         if (placeholders.containsKey(cell.substring(1))) {
  218.             return (String) placeholders.get(cell.substring(1));
  219.         }
  220.         else {
  221.             return cell;
  222.         }
  223.     }
  224.    
  225.     /**
  226.      * Get the value in ArrayList from the Hashmap by key.
  227.      * The <b>key</b> is the placeholder from your template Excel file.
  228.      * @param cell A cell in instance of String
  229.      * @return The specified value for the specified placeholder
  230.      * @since 2.0
  231.      */
  232.     private ArrayList<ArrayList> getValueArr(String cell) {
  233.         if (placeholders.containsKey(cell.substring(1))) {
  234.             return (ArrayList<ArrayList>) placeholders.get(cell.substring(1));
  235.         }
  236.         else {
  237.             // Just create an empty ArrayList to avoid NullPointerException
  238.             ArrayList<ArrayList> a = new ArrayList<>();
  239.             ArrayList<String> b = new ArrayList<>();
  240.             b.add("");
  241.             a.add(b);
  242.             return a;
  243.         }
  244.     }
  245.    
  246.     /**
  247.      * Save/Write the resulting excel file to the specified file path. <br />
  248.      * Any caught exception such as <b>IOException</b> will interrupt the saving of file. <br /> <br />
  249.      * <i>
  250.      * Warning: This will replace the old file if there's already exists!
  251.      * If you want to avoid overwritten of file, please do a simple evaluation first
  252.      * before calling this method.
  253.      * </i>
  254.      * @param wb An instance of XSSFWorkbook, a class for MS Excel <b>2007</b> support.
  255.      *           This must contain the rows and cell that is ready for saving.
  256.      * @return True if no error occurs in process of saving, otherwise false.
  257.      * @since 1.0
  258.      */
  259.     private boolean doSaveExcelFile(XSSFWorkbook wb) {
  260.         try (FileOutputStream writeFile = new FileOutputStream(save_path)) {
  261.             wb.write(writeFile);
  262.             writeFile.flush();
  263.             writeFile.close();
  264.             return true;
  265.         } catch (IOException e) {
  266.             System.out.println("[ERROR] Encountered an error while saving the file.\n" + e.getLocalizedMessage());
  267.             return false;
  268.         }
  269.     }
  270.    
  271.     /**
  272.      * Check the nullity or emptiness value of save path. <br /> <br />
  273.      * <i>
  274.      * Note: File name will be out.xlsx by default.
  275.      * </i>
  276.      * @return If null or empty, the directory will be moved to your Desktop,
  277.      *         otherwise return the user-specified path.
  278.      * @since 1.0
  279.      */
  280.     private String checkSavePath(String save_path) {
  281.         if (save_path == null || save_path.isEmpty()) {
  282.             String path;
  283.             if (OSValidator.isWindows()) {
  284.                 path = System.getenv("userprofile") + "/Desktop/out.xlsx";
  285.             }
  286.             else {
  287.                 path = System.getenv("HOME") + "/Desktop/out.xlsx";
  288.             }
  289.             System.out.println("[WARNING] save_path has null or empty value! This will be moved to " + path);
  290.             return path;
  291.         }
  292.         else {
  293.             return save_path;
  294.         }
  295.     }
  296.    
  297. }
  298.  
  299. /*** OLD VERSIONS ***/
  300. /* Version 1.5
  301. // Iterate the row from template
  302. for (int row_i = 0; row_i < sheet.getPhysicalNumberOfRows(); row_i++) {
  303.     row = sheet.getRow(row_i);
  304.     // Iterate the cell of the current row from the template
  305.     for (int cell_i = 0; cell_i < row.getPhysicalNumberOfCells(); cell_i++) {
  306.         cell = row.getCell(cell_i);
  307.         String cell_str = cell.toString();
  308.         if (isPlaceholder(cell_str)) {
  309.             cell.setCellValue(getValue(cell_str));
  310.         }
  311.     }
  312. }
  313. */
  314.  
  315. /* Version 1.0
  316. // Iterate the row
  317. while (row_iter.hasNext()) {
  318.     XSSFRow xrow = (XSSFRow) row_iter.next();
  319.     Iterator cell_iter = xrow.cellIterator();
  320.     row = sheet_new.createRow(row_index++);
  321.  
  322.     // Iterate the cell from current row
  323.     while (cell_iter.hasNext()) {
  324.         XSSFCell xcell = (XSSFCell) cell_iter.next();
  325.         String cell_str = xcell.toString();
  326.         cell = row.createCell(cell_index);
  327.  
  328.         // Search for available placeholder
  329.         if (isPlaceholder(cell_str)) {
  330.             cell.setCellValue(getValue(cell_str));
  331.         }
  332.         else {
  333.             cell.setCellValue(cell_str);
  334.         }
  335.         cell_index++;
  336.     }
  337.     cell_index = 0;
  338. }
  339. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement