POI Excel Basics (1)

POI 5.2.3
official website

github

POI-HSSF and POI-XSSF/SXSSF Java API for accessing files in Microsoft Excel format

HSSF: is the abbreviation of Horrible SpreadSheet Format, that is, "horrible spreadsheet format"

    是操作Excel97-2003版本,扩展名为.xls。

XSSF:

    是操作Excel2007版本开始,扩展名为.xlsx。

SXSSF:

    是在XSSF基础上,POI3.8版本开始提供的一种支持低内存占用的操作方式,扩展名为.xlsx。

Some differences between different versions of Excel are as follows. These limitations actually indirectly limit the API functions provided by POI.

1. The number of rows and columns supported

    Excel97-2003版本,一个sheet最大行数65536,最大列数256。

    Excel2007版本开始,一个sheet最大行数1048576,最大列数16384。

2. File size

    .xlsx文件比.xls的压缩率高,也就是相同数据量下,.xlsx的文件会小很多。

3. Compatibility

    Excel97-2003版本是不能打开.xlsx文件的。

    Excel2007开始的版本是可以打开.xls文件的。

overview

HSSF is the POI project's pure Java implementation of the Excel '97(-2007) file format. XSSF is the POI project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.

HSSF and XSSF provide methods for reading spreadsheets, creating, modifying, reading and writing XLS spreadsheets. They provide:

  • Low-level structure for special needs
  • Event model API for efficient read-only access ( eventmodel api)
  • Complete User Model API for creating, reading and modifying XLS files

For those converting from a pure HSSF user model who wish to use a federated SS user model to support HSSF and XSSF, see the SS user model conversion guide .

Another way to generate spreadsheets is through Cocoon serializers (but you'll still be using HSSF indirectly). With Cocoon, you can serialize any XML data source (for example, it might be an ESQL page output in SQL) by simply applying a stylesheet and specifying a serializer.

org.apache.poi.hssf.eventusermodelIf you're just reading spreadsheet data, then use the package or the api org.apache.poi.xssf.eventusermodelin the package , depending on your file format eventmodel .

If you want to modify spreadsheet data, you use usermodelthe api. You can also generate spreadsheets this way.

Note that the usermodel system has a higher memory footprint than the underlying eventmodel system, but its main advantage is that it is much simpler to use. Also note that since the new XSSF supported Excel 2007 OOXML (.xlsx) files are XML based, the memory footprint to process them is higher than the older HSSF supported binary files (.xls).

SXSSF (Since POI 3.8 beta3)

Starting with 3.8-beta3, POI provides a low-memory SXSSF API built on top of XSSF.

SXSSF is an API-compatible streaming extension of XSSF for situations where very large spreadsheets must be generated, and heap space is limited. SXSSF achieves low memory footprint by restricting access to lines within a sliding window, while XSSF allows access to all lines in a document . Old rows that are no longer in the window become inaccessible when they are written to disk.

In auto-refresh mode, 可以指定访问窗口的大小, to keep a certain number of rows in memory. When this value is reached, creating additional rows will cause the row with the lowest index to be removed from the access window and written to disk . Alternatively, 窗口大小可以设置为动态增长; it can be periodically pruned as needed by explicit calls flushRows(int keepRows).

Due to the streaming nature of the implementation, there are the following limitations compared to XSSF:

  • Only a limited number of rows can be accessed at a point in time.
  • Not supported Sheet.clone().
  • Does not support formula calculation

See the SXSSF How-To for more details

The table below outlines the comparative features of POI's Spreadsheet API:

insert image description here

1. Developer's Guide to HSSF and XSSF Features

Want to read and write spreadsheets using HSSF and XSSF? This guide is for you. If you want a more in-depth look at the HSSF and XSSF user apis, see the HOWTO guide , as it contains practical descriptions of how to use these things.

1.1 Create a new Workbook (workbook)

Workbook wb = new XSSFWorkbook();
...
try (OutputStream fileOut = new FileOutputStream("workbook.xlsx")) {
    
    
    wb.write(fileOut);
}

1.2 Create a new Sheet

Workbook wb = new HSSFWorkbook();  // or new XSSFWorkbook();
Sheet sheet1 = wb.createSheet("new sheet");
Sheet sheet2 = wb.createSheet("second sheet");
// Note that sheet name is Excel must not exceed 31 characters
// and must not contain any of the any of the following characters:
// 0x0000
// 0x0003
// colon (:)
// backslash (\)
// asterisk (*)
// question mark (?)
// forward slash (/)
// opening square bracket ([)
// closing square bracket (])
// You can use org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)}
// for a safe way to create valid names, this utility replaces invalid characters with a space (' ')
String safeName = WorkbookUtil.createSafeSheetName("[O'Brien's sales*?]"); // returns " O'Brien's sales   "
Sheet sheet3 = wb.createSheet(safeName);
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}

1.3 Create cells

Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it.
// 行和单元格都是从0开始。
Row row = sheet.createRow(0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(
     createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}

1.4 Create a date cell

Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(0);
// Create a cell and put a date value in it.  The first cell is not styled as a date.
Cell cell = row.createCell(0);
cell.setCellValue(new Date());

// we style the second cell as a date (and time).  It is important to
// create a new cell style from the workbook otherwise you can end up
// modifying the built in style and effecting not only this cell but other cells.
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(
	    createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);

//you can also set date as java.util.Calendar
cell = row.createCell(2);
cell.setCellValue(Calendar.getInstance());
cell.setCellStyle(cellStyle);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}

1.5 Handling different types of cells

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
Row row = sheet.createRow(2);
row.createCell(0).setCellValue(1.1);
row.createCell(1).setCellValue(new Date());
row.createCell(2).setCellValue(Calendar.getInstance());
row.createCell(3).setCellValue("a string");
row.createCell(4).setCellValue(true);
row.createCell(5).setCellType(CellType.ERROR);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}

1.6 Files vs InputStreams

When opening a workbook, the workbook can either be loaded from or .xls HSSFWorkbook or .xlsx FileXSSFWorkbook InputStream. Using Fileobjects allows lower memory consumption while InputStreamrequiring more memory as it has to buffer the entire file.

It's easy to use one of these if WorkbookFactory:

// Use a file
Workbook wb = WorkbookFactory.create(new File("MyExcel.xls"));
// Use an InputStream, needs more memory
Workbook wb = WorkbookFactory.create(new FileInputStream("MyExcel.xlsx"));

If using HSSFWorkbookor directly XSSFWorkbook, you should usually pass POIFSFileSystemthe or OPCPackage, for full control over the lifecycle (including closing the file on completion):

// HSSFWorkbook, File
POIFSFileSystem fs = new POIFSFileSystem(new File("file.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
....
fs.close();
// HSSFWorkbook, InputStream, needs more memory
POIFSFileSystem fs = new POIFSFileSystem(myInputStream);
HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
// XSSFWorkbook, File
OPCPackage pkg = OPCPackage.open(new File("file.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(pkg);
....
pkg.close();
// XSSFWorkbook, InputStream, needs more memory
OPCPackage pkg = OPCPackage.open(myInputStream);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
....
pkg.close();

1.7 Demonstrating various alignment options

public static void main(String[] args) throws Exception {
    
    
    Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
    Sheet sheet = wb.createSheet();
    Row row = sheet.createRow(2);
    
    // 设置行高使用HSSFRow对象的setHeight和setHeightInPoints方法,
	// 这两个方法的区别在于setHeightInPoints的单位是点,而setHeight的单位是1/20个点
    row.setHeightInPoints(30);
    createCell(wb, row, 0, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM);
    createCell(wb, row, 1, HorizontalAlignment.CENTER_SELECTION, VerticalAlignment.BOTTOM);
    createCell(wb, row, 2, HorizontalAlignment.FILL, VerticalAlignment.CENTER);
    createCell(wb, row, 3, HorizontalAlignment.GENERAL, VerticalAlignment.CENTER);
    createCell(wb, row, 4, HorizontalAlignment.JUSTIFY, VerticalAlignment.JUSTIFY);
    createCell(wb, row, 5, HorizontalAlignment.LEFT, VerticalAlignment.TOP);
    createCell(wb, row, 6, HorizontalAlignment.RIGHT, VerticalAlignment.TOP);
    // Write the output to a file
    try (OutputStream fileOut = new FileOutputStream("xssf-align.xlsx")) {
    
    
        wb.write(fileOut);
    }
    wb.close();
}
/**
 * Creates a cell and aligns it a certain way.
 *
 * @param wb     the workbook
 * @param row    the row to create the cell in
 * @param column the column number to create the cell in
 * @param halign the horizontal alignment for the cell.
 * @param valign the vertical alignment for the cell.
 */
private static void createCell(Workbook wb, Row row, int column, HorizontalAlignment halign, VerticalAlignment valign) {
    
    
    Cell cell = row.createCell(column);
    cell.setCellValue("Align It");
    CellStyle cellStyle = wb.createCellStyle();
    cellStyle.setAlignment(halign);
    cellStyle.setVerticalAlignment(valign);
    cell.setCellStyle(cellStyle);
}

1.8 Using borders

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(1);
// Create a cell and put a value in it.
Cell cell = row.createCell(1);
cell.setCellValue(4);
// Style the cell with borders all around.
CellStyle style = wb.createCellStyle();
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREEN.getIndex());
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.BLUE.getIndex());
style.setBorderTop(BorderStyle.MEDIUM_DASHED);
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
cell.setCellStyle(style);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

1.9 Iterating over rows and cells

Sometimes you want to just iterate over all sheets in a workbook, all rows in a sheet, or all cells in a row. This can be achieved with a simple for loop.

These iterators can be obtained by calling workbook.sheetIterator(), sheet.rowIterator(), and row.cellIterator(), or implicitly using a for-each loop. Note that rowIteratorand cellIteratoriterate over the created rows or cells, skipping empty rows and cells.

for (Sheet sheet : wb ) {
    
    
    for (Row row : sheet) {
    
    
        for (Cell cell : row) {
    
    
            // Do something here
        }
    }
}

1.10 Iterate cells, control missing / blank cells (missing / blank cells)

In some cases, when iterating, you need full control over how missing or blank rows and cells are handled, and you need to ensure that every cell is visited, not just those defined in the file. (CellIterator will only return cells defined in the file, which are mostly those that have values ​​or styles, but it depends on Excel).

In this case, you should get the first and last column information of a row, and then call getCell(int, MissingCellPolicy)to get the cell. Use MissingCellPolicy to control how blank or empty cells are handled.


// Decide which rows to process
int rowStart = Math.min(15, sheet.getFirstRowNum());
int rowEnd = Math.max(1400, sheet.getLastRowNum());
for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
    
    
   Row r = sheet.getRow(rowNum);
   if (r == null) {
    
    
      // This whole row is empty
      // Handle it as needed
      continue;
   }
   int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);
   for (int cn = 0; cn < lastColumn; cn++) {
    
    
      Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
      if (c == null) {
    
    
         // The spreadsheet is empty in this cell
      } else {
    
    
         // Do something useful with the cell's contents
      }
   }
}

1.11 Get cell content

To get the contents of a cell, you first need to know what type of cell it is (for example, asking a string cell for its numeric content will get you back NumberFormatException). You'll want to switch the cell's type, then call the appropriate getter for that cell.

In the code below, we loop through each cell in a worksheet, print out the cell's reference (eg A3), and then print out the cell's contents.

// import org.apache.poi.ss.usermodel.*;
DataFormatter formatter = new DataFormatter();
Sheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
    
    
    for (Cell cell : row) {
    
    
        CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
        System.out.print(cellRef.formatAsString());
        System.out.print(" - ");
        // get the text that appears in the cell by getting the cell value and applying any data formats (Date, 0.00, 1.23e9, $1.23, etc)
        String text = formatter.formatCellValue(cell);
        System.out.println(text);
        // Alternatively, get the value and format it yourself
        switch (cell.getCellType()) {
    
    
            case CellType.STRING:
                System.out.println(cell.getRichStringCellValue().getString());
                break;
            case CellType.NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
    
    
                    System.out.println(cell.getDateCellValue());
                } else {
    
    
                    System.out.println(cell.getNumericCellValue());
                }
                break;
            case CellType.BOOLEAN:
                System.out.println(cell.getBooleanCellValue());
                break;
            case CellType.FORMULA:
                System.out.println(cell.getCellFormula());
                break;
            case CellType.BLANK:
                System.out.println();
                break;
            default:
                System.out.println();
        }
    }
}

1.12 Text Extraction

For most text extraction needs, the standard ExcelExtractorclasses should provide everything you need.

try (InputStream inp = new FileInputStream("workbook.xls")) {
    
    
    HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(inp));
    ExcelExtractor extractor = new ExcelExtractor(wb);
    extractor.setFormulasNotResults(true);
    extractor.setIncludeSheetNames(false);
    String text = extractor.getText();
    wb.close();
}

For really fancy text extraction, XLS to CSV, etc., have a look at/poi-examples/src/main/java/org/apache/poi/examples/hssf/eventusermodel/XLS2CSVmra.java

1.13 Fill and color

Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(1);
// Aqua background
CellStyle style = wb.createCellStyle();
style.setFillBackgroundColor(IndexedColors.AQUA.getIndex());
style.setFillPattern(FillPatternType.BIG_SPOTS);
Cell cell = row.createCell(1);
cell.setCellValue("X");
cell.setCellStyle(style);
// Orange "foreground", foreground being the fill foreground not the font color.
style = wb.createCellStyle();
style.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell = row.createCell(2);
cell.setCellValue("X");
cell.setCellStyle(style);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

1.14 Merging cells

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellValue("This is a test of merging");
sheet.addMergedRegion(new CellRangeAddress(
        1, //first row (0-based)
        1, //last row  (0-based)
        1, //first column (0-based)
        2  //last column  (0-based)
));
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

1.15 Using fonts

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(1);
// Create a new font and alter it.
Font font = wb.createFont();
font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);
// Fonts are set into a style so create a new one to use.
CellStyle style = wb.createCellStyle();
style.setFont(font);
// Create a cell and put a value in it.
Cell cell = row.createCell(1);
cell.setCellValue("This is a test of fonts");
cell.setCellStyle(style);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

Note that the maximum number of unique fonts in a workbook is limited to 32767. You should reuse fonts across your application, rather than creating fonts for each cell. Example:
Wrong:

for (int i = 0; i < 10000; i++) {
    
    
    Row row = sheet.createRow(i);
    Cell cell = row.createCell(0);
    CellStyle style = workbook.createCellStyle();
    Font font = workbook.createFont();
    font.setBoldweight(Font.BOLDWEIGHT_BOLD);
    style.setFont(font);
    cell.setCellStyle(style);
}

Correct:

CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(font);
for (int i = 0; i < 10000; i++) {
    
    
    Row row = sheet.createRow(i);
    Cell cell = row.createCell(0);
    cell.setCellStyle(style);
}

1.16 Custom Colors

XSSF:

XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell( 0);
cell.setCellValue("custom XSSF colors");
XSSFCellStyle style1 = wb.createCellStyle();
style1.setFillForegroundColor(new XSSFColor(new java.awt.Color(128, 0, 128), new DefaultIndexedColorMap()));
style1.setFillPattern(FillPatternType.SOLID_FOREGROUND);

1.17 Reading and rewriting workbooks

try (InputStream inp = new FileInputStream("workbook.xls")) {
    
    
//InputStream inp = new FileInputStream("workbook.xlsx");
    Workbook wb = WorkbookFactory.create(inp);
    Sheet sheet = wb.getSheetAt(0);
    Row row = sheet.getRow(2);
    Cell cell = row.getCell(3);
    if (cell == null)
        cell = row.createCell(3);
    cell.setCellType(CellType.STRING);
    cell.setCellValue("a test");
    // Write the output to a file
    try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
        wb.write(fileOut);
    }
}

1.18 Using line breaks in cells

Workbook wb = new XSSFWorkbook();   //or new HSSFWorkbook();
Sheet sheet = wb.createSheet();
Row row = sheet.createRow(2);
Cell cell = row.createCell(2);
cell.setCellValue("Use \n with word wrap on to create a new line");
//to enable newlines you need set a cell styles with wrap=true
CellStyle cs = wb.createCellStyle();
cs.setWrapText(true);
cell.setCellStyle(cs);
//increase row height to accommodate two lines of text
row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints()));
//adjust column width to fit the content
sheet.autoSizeColumn(2);
try (OutputStream fileOut = new FileOutputStream("ooxml-newlines.xlsx")) {
    
    
    wb.write(fileOut);
}
wb.close();

1.19 Data Formatting'

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("format sheet");
CellStyle style;
DataFormat format = wb.createDataFormat();
Row row;
Cell cell;
int rowNum = 0;
int colNum = 0;
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("0.0"));
cell.setCellStyle(style);
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("#,##0.0000"));
cell.setCellStyle(style);
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

1.20 Fit Sheet to One Page

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("format sheet");
PrintSetup ps = sheet.getPrintSetup();
sheet.setAutobreaks(true);
ps.setFitHeight((short)1);
ps.setFitWidth((short)1);
// Create various cells and rows for spreadsheet.
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    
    
    wb.write(fileOut);
}
wb.close();

Images

Images are part of the drawing support. To add an image, just call it on the drawing parent element (DrawingPatriarch) createPicture(). At the time of writing, the following types are supported:

  • PNG
  • JPG
  • BACK

It should be noted that any existing drawing may be erased once the image is added to the worksheet.

//create a new workbook
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
//add picture data to this workbook.
InputStream is = new FileInputStream("image1.jpeg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
CreationHelper helper = wb.getCreationHelper();
//create sheet
Sheet sheet = wb.createSheet();
// Create the drawing patriarch.  This is the top level container for all shapes.
Drawing drawing = sheet.createDrawingPatriarch();
//add a picture shape
ClientAnchor anchor = helper.createClientAnchor();
//set top-left corner of the picture,
//subsequent call of Picture#resize() will operate relative to it
anchor.setCol1(3);
anchor.setRow1(2);
Picture pict = drawing.createPicture(anchor, pictureIdx);
//auto-size picture relative to its top-left corner
pict.resize();
//save workbook
String file = "picture.xls";
if(wb instanceof XSSFWorkbook) file += "x";
try (OutputStream fileOut = new FileOutputStream(file)) {
    
    
    wb.write(fileOut);
}

Picture.resize()Only available for JPEG and PNG. Other formats are not currently supported.

Guess you like

Origin blog.csdn.net/chinusyan/article/details/130706238