Total Pageviews

Showing posts with label POI. Show all posts
Showing posts with label POI. Show all posts

2015/05/11

[Apache POI] How to read empty row in excel file

Problem
Here is my excel file

I will read excel from top to down, and will start to read from row 4 and write data into database.
Here is my code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 // file extension validation
 String extension = StringUtils.upperCase(FilenameUtils.getExtension(fileName));
 Integer startingRow = 3;
 
 Workbook workbook = null;
 Sheet sheet = null;

 if ("XLS".equals(extension)) {
     // Get the workbook instance for XLS file
     workbook = new HSSFWorkbook(inputStream);
 } else if ("XLSX".equals(extension)) {
     // Get the workbook instance for XLSX file
     workbook = new XSSFWorkbook(inputStream);
 } else {
     String errorMsg = "只接受副檔名為xls與xlsx的檔案, fileName = " + fileName;
     throw new RuntimeException(errorMsg);
 }

 // Get the specific sheet from the workbook
 sheet = workbook.getSheetAt(0);

 Iterator<Row> rowIterator = sheet.iterator();
 int rowCount = 0;
 while (rowIterator.hasNext()) {
     Row row = rowIterator.next();
     if (rowCount < startingRow) {
     //do nothing
     } else {
     //start to read and write data into database
     }
     rowCount++;
 }

But, apply this approach it will read from row 5. Because of the first row is null, Apache POI will skip empty row.

Solution
Utilize for-loop instead of while-loop, then it will not skip empty row:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  // file extension validation
 String extension = StringUtils.upperCase(FilenameUtils.getExtension(fileName));
 Integer startingRow = 3;

 Workbook workbook = null;
 Sheet sheet = null;

 if ("XLS".equals(extension)) {
     // Get the workbook instance for XLS file
     workbook = new HSSFWorkbook(inputStream);
 } else if ("XLSX".equals(extension)) {
     // Get the workbook instance for XLSX file
     workbook = new XSSFWorkbook(inputStream);
 } else {
     String errorMsg = "只接受副檔名為xls與xlsx的檔案, fileName = " + fileName;
     throw new RuntimeException(errorMsg);
 }

 // Get the specific sheet from the workbook
 sheet = workbook.getSheetAt(0);

 // get last row number
 int rowEnd = sheet.getLastRowNum();

 for (int rowNum = startingRow; rowNum <= rowEnd; rowNum++) {
     Row row = sheet.getRow(rowNum);
    
 }


Reference
[1] http://poi.apache.org/spreadsheet/quick-guide.html#Iterator

2015/03/20

[Apache POI] HSSFWorkbook and XSSFWorkbook

According to the two posts....
http://albert-myptc.blogspot.tw/2015/03/orgapachepoipoifsfilesystemofficexmlfil.html
http://albert-myptc.blogspot.tw/2015/03/invalidformatexception-package-should.html

If you would like to read xls file, you should utilize HSSFWorkbook. If you misuse it, i.e. upload xlsx file, it will throw exception :  org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

If you would like to read xlsx file, you should utilize XSSFWorkbook. If you misuse it, i.e. upload xls file, it will throw exception : 
org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]


Hence, if I would like to accept the both, here is my code snippet
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
try {
    // file extension validation
    String extension = StringUtils.upperCase(FilenameUtils.getExtension(fileName));
    if (!("XLS".equals(extension)) && !("XLSX".equals(extension))) {
        String errorMsg = "只接受副檔名為xls與xlsx的檔案, fileName = " + fileName;
        throw new RuntimeException(errorMsg);
    }

    Workbook workbook = null;
    Sheet sheet = null;

    if ("XLS".equals(extension)) {
        // Get the workbook instance for XLS file
        workbook = new HSSFWorkbook(inputStream);
    } else if ("XLSX".equals(extension)) {
        // Get the workbook instance for XLSX file
        workbook = new XSSFWorkbook(inputStream);
    }

    // Get the specific sheet from the workbook
    sheet = workbook.getSheetAt(0);

    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0));
    }

} catch (IOException e) {
    throw e;
}




[Apache POI] org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents

Problem
I have a file upload function, which accept xlsx and xls file.




Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for Excel file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }

But as I upload xlsx file, it throw this exception

1
2
3
4
5
6
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:131) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:104) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:128) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:342) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:323) ~[poi-3.10-FINAL.jar:3.10-FINAL]

Solution
To open an xlsx (Office Open XML) file, you should use XSSFWorkbook instead of HSSFWorkbook, which is used for xls (Excel 97-2003) files.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for Excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0).toString());
    }
} catch (IOException e) {
    throw e;
}


Reference

[Apache POI] InvalidFormatException: Package should contain a content type part [M1.13]

Problem
I have a file upload function, which accept xlsx and xls file.


Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0));
    }
} catch (IOException e) {
    throw e;
}


But as I upload xls file, it throw this exception
1
2
3
 org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
  at org.apache.poi.util.PackageHelper.open(PackageHelper.java:41) ~[poi-ooxml-3.9.jar:3.9]
  at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:204) ~[poi-ooxml-3.9.jar:3.9]

Solution
The error is telling you that POI couldn't find a core part of the OOXML file. Your file isn't a valid OOXML file, let alone a valid .xlsx file.  So you need to use HSSFWorkbook instead of XSSFWorkbook.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for XLS file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }



Reference
[1] http://stackoverflow.com/questions/6758364/getting-exceptionorg-apache-poi-openxml4j-exception-no-content-type-m1-13

2014/10/29

How to read Excel file by Apache POI

Requirement
Assume we have an excel file, we would like to read the data which in sheet2.
We only need the amount in Column E and column I, and the value of Column A show be 'XXX年'

Here has sample code (focus on Line 17~33)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class POITest {  
  private final static Logger LOG = LoggerFactory.getLogger(POITest.class);  
  /**  
   * The main method.  
   *   
   * @param args  
   *      the arguments  
   * @throws IOException  
   *       Signals that an I/O exception has occurred.  
    */  
   public static void main(String[] args) throws IOException {  
     String testFile = "D:\\work\\ifms\\TestFiles\\4102294114W75Y7OW0.xls";  
     Integer sheetNum = 1;  
     FileInputStream file = null;  
     try {  
       file = new FileInputStream(new File(testFile));  
       // Get the workbook instance for XLS file  
       HSSFWorkbook workbook = new HSSFWorkbook(file);  
       // Get the specific sheet from the workbook  
       HSSFSheet sheet = workbook.getSheetAt(sheetNum);  
       // Get iterator to all the rows in current sheet  
       Iterator rowIterator = sheet.iterator();  
       List list = new ArrayList<>();  
       while (rowIterator.hasNext()) {  
         Row row = rowIterator.next();  
         if (StringUtils.indexOf(row.getCell(0).toString(), "年") > 0) {//condition  
           Test test = new POITest().new Test();  
           test.setYear(row.getCell(0).toString());//column A  
           test.setGdp(new BigDecimal(row.getCell(4).getNumericCellValue()));//column E  
           test.setGnp(new BigDecimal(row.getCell(8).getNumericCellValue()));//column I  
           list.add(test);  
         }  
       }  
       for (Test vo : list) {  
         LOG.debug("vo=" + vo.toString());  
       }  
     } catch (FileNotFoundException e) {  
       throw new RuntimeException(e);  
     } catch (IOException e) {  
       throw new RuntimeException(e);  
     } finally {  
       file.close();  
     }  
   }  
   private class Test {  
     private String year;  
     private BigDecimal gdp;  
     private BigDecimal gnp;  
     public String getYear() {  
       return year;  
     }  
     public void setYear(String year) {  
       this.year = year;  
     }  
     public BigDecimal getGdp() {  
       return gdp;  
     }  
     public void setGdp(BigDecimal gdp) {  
       this.gdp = gdp;  
     }  
     public BigDecimal getGnp() {  
       return gnp;  
     }  
     public void setGnp(BigDecimal gnp) {  
       this.gnp = gnp;  
     }  
     public String toString() {  
       return ToStringBuilder.reflectionToString(this);  
     }  
   }  
 } 

Here is the log which print in console
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@2d7349d7[year=80,gdp=4958220,gnp=5093770]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@6bf4d990[year=81,gdp=5534544,gnp=5655306]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@17f7b44f[year=82,gdp=6110101,gnp=6224145]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@75ebad4[year=83,gdp=6685505,gnp=6793022]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@5c3bb813[year=84,gdp=7277545,gnp=7388464]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@54b216b3[year=85,gdp=7906075,gnp=8015577]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@77f06d35[year=86,gdp=8574784,gnp=8664395]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@4991f017[year=87,gdp=9204174,gnp=9272725]  
[main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@c299bbd[year=88,gdp=9649049,gnp=9739567]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@7faf9b87[year=89,gdp=10187394,gnp=10326952]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@620bfd8e[year=90,gdp=9930387,gnp=10122411]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@133a7ec[year=91,gdp=10411639,gnp=10654141]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@66557791[year=92,gdp=10696257,gnp=11025130]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@751d0513[year=93,gdp=11365292,gnp=11737391]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@44385e76[year=94,gdp=11740279,gnp=12031145]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@50c1b7f7[year=95,gdp=12243471,gnp=12555170]  
 [main] DEBUG g.n.e.w.c.Ets402rReportController - vo=gov.nta.ets.web.controller.Ets402rReportController$Test@5e14e28c[year=96,gdp=12910511,gnp=13243277] 

Reference
[1] http://viralpatel.net/blogs/java-read-write-excel-file-apache-poi/

2013/11/15

How to adjust column width to fit the contents in Apache POI

Problem
I utilized Apache POI to write data into excel file. But I found out each cell width has the same default width, it does not adjust it's width based on its contents.

Solution
You can call autoSizeColumn method in HSSFSheet to fix this problem.
Here is the JavaDoc: http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFSheet.html#autoSizeColumn(int, boolean)
If you have 10 columns, you need to call autoSizeColumn 10 times in for-loop.
For example.
1:          for (int resizeCnt = 0; resizeCnt < pdateSet.size() + 3; resizeCnt++) {  
2:            sheet.autoSizeColumn(resizeCnt);  
3:          }  
Check the result after we call autoSizeColumn. 
You can see some columns' width may not really fit the contents, but it's much better than the original one.

2013/11/14

How to set currecny cell to right-justified horizontal alignment and apply 1000 separator in Apache POI

Problem
We utilized Apache POI to write excel, but some currency cells do not right-justified horizontal alignment and do not apply 1000 separator.

Solution
1:          //create CellStyle, and define style information  
2:          CellStyle cs = workbook.createCellStyle();  
3:          cs.setBorderBottom((short) 1);  
4:          cs.setBorderTop((short) 1);  
5:          cs.setBorderLeft((short) 1);  
6:          cs.setBorderRight((short) 1);  
7:          cs.setAlignment(CellStyle.ALIGN_RIGHT);//right-justified horizontal alignment  
8:          cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));//apply 1000 separator  
9:          .....  
10:          .....  
11:          //set cs, the CellStyle with style information which we defined, into cell  
12:          cell.setCellStyle(cs);  


For more DataFormat information, you can check it:

Check the result

Here you can find more useful information: http://javacrazyer.iteye.com/blog/894850

2013/11/12

POI 常用API筆記

參考資料來源:http://become.wei-ting.net/2011/11/poiexcel.html

1:  File tempFile = new File(filePath,filename);//建立儲存檔案  
2:  Workbook workbook = new HSSFWorkbook();//建立Excel物件  
3:  String safeName = WorkbookUtil.createSafeSheetName(SHEETNAME);   
4:  Sheet sheet = workbook.createSheet(safeName);//建立工作表  
5:  Row row1 = sheet.createRow((short)0);//建立工作列  
6:  //字型設定  
7:  Font font = workbook.createFont();  
8:  font.setColor(HSSFColor.WHITE.index);//顏色  
9:  font.setBoldweight(Font.BOLDWEIGHT_BOLD); //粗體  
10:  //設定儲存格格式  
11:  CellStyle styleRow1 = workbook.createCellStyle();  
12:  styleRow1.setFillForegroundColor(HSSFColor.GREEN.index);//填滿顏色  
13:  styleRow1.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);  
14:  styleRow1.setFont(font);//設定字體  
15:  styleRow1.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平置中  
16:  styleRow1.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直置中  
17:  //設定框線  
18:  styleRow1.setBorderBottom((short)1);  
19:  styleRow1.setBorderTop((short)1);  
20:  styleRow1.setBorderLeft((short)1);  
21:  styleRow1.setBorderRight((short)1);  
22:  styleRow1.setWrapText(true);//自動換行  
23:  Cell cell = row1.createCell(0);//建立儲存格  
24:  cell.setCellStyle(styleRow1);//套用格式  
25:  cell.setCellValue(CELLTEXT);//設定內容  
26:  sheet.autoSizeColumn(0);//自動調整欄位寬度  
27:  //儲存檔案  
28:  FileOutputStream fileOut = new FileOutputStream(tempFile);  
29:  workbook.write(fileOut);  
30:  fileOut.close();