2

【开源库推荐】#4 Poi-办公文档处理库 - Stars-one

 1 year ago
source link: https://www.cnblogs.com/stars-one/p/16966037.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本文为作者原创,允许转载,不过请在文章开头明显处注明链接和出处!!! 谢谢配合~
作者:stars-one
链接:https://www.cnblogs.com/stars-one/p/16966037.html

本篇大约有9488个字,阅读预计需要11.86分钟


原文:【开源库推荐】 #4 Poi-办公文档处理库 - Stars-One的杂货小窝

github仓库apache/poi

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。.NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。

提示:下文代码示例有Java和Kotlin形式

PS: 目前不确定此库能否在Android平台上使用,但从Github上的搜索结果来看,应该需要移植

POI结构说明

包名称说明

  • HSSF提供读写Microsoft Excel XLS格式档案的功能。
  • XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能。
  • HWPF提供读写Microsoft Word DOC格式档案的功能。
  • HSLF提供读写Microsoft PowerPoint格式档案的功能。
  • HDGF提供读Microsoft Visio格式档案的功能。
  • HPBF提供读Microsoft Publisher格式档案的功能。
  • HSMF提供读Microsoft Outlook格式档案的功能。

目前只研究了读写表格的相关操作,至于Word等其他文件还没有细致研究,之后有研究了再补充了..

读写Excel

首先,先引入依赖

<!--xls(03)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>

<!--xlsx(07)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>

poi是只支持xls格式,而poi-ooxml则可以支持xlsx格式

1.读取excel文件数据

上面我们也是知道,由于存在两种格式,所以我们的写法上得注意一下

  • XSSFWorkbook 对应xls文件
  • HSSFWorkbook 对应xlsx文件

由于XSSFWorkbookHSSFWorkbook都是实现的Workbook接口,所以可利用到多态的原理来编写代码,达到兼容写法

fun main(args: Array<String>) {

    val file = File("D:\\download\\test.xlsx")
    
    var workbook: Workbook? = null

    if (file.extension.toLowerCase() == "xlsx") {
        //xlsx
        workbook = XSSFWorkbook(file)
    }
    if (file.extension.toLowerCase() == "xls") {
        //xls
        workbook = HSSFWorkbook(FileInputStream(file))
    }

    workbook?.let {
        val sheet = workbook.getSheetAt(0)

        //读取第一行第一列单元格数据
        val firstColumn = sheet.getRow(0).first()

        //需要判断一下但单元格的类型
        if (firstColumn.cellType == CellType.STRING) {
            println(firstColumn.stringCellValue)
        }
        workbook.close()
    }
}

PS:就是觉得有些神奇的是,XSSFWorkbook构造函数可以接收File类型的对象参数,而HSSFWorkbook只能接收FileInputSteam

2.创建execl文件数据

val file = File("D:\\download\\myoutput.xlsx")
val workbook: Workbook = XSSFWorkbook()
//val workbook: Workbook =  HSSFWorkbook()

val sheet = workbook.createSheet("sheet0")
val row = sheet.createRow(0)
val cell = row.createCell(0)
cell.cellType = CellType.STRING
cell.setCellValue("hello world")
//输出到文件
workbook.write(FileOutputStream(file))
workbook.close()
1210268-20221208141153073-2027945951.png

读写Word

可以查看此教程Apache POI Word(docx) 入门示例教程

暂无需求,还没有细研究

除此之外,可以选择Word模板然后注入对应的数据进去,推荐使用Poi-tl Documentation

补充-EXCEL常用操作方法

1、得到Excel常用对象

POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls")); 
//得到Excel工作簿对象 
HSSFWorkbook wb = new HSSFWorkbook(fs); 
//得到Excel工作表对象 
HSSFSheet sheet = wb.getSheetAt(0); 
//得到Excel工作表的行 
HSSFRow row = sheet.getRow(0); 
//得到Excel工作表指定行的单元格 
HSSFCell cell = row.getCell(0); 
//得到单元格样式
cellStyle = cell.getCellStyle();

2、建立Excel常用对象

HSSFWorkbook wb = new HSSFWorkbook(); 
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short)0); 
HSSFCell cell = sheet.createCell((short)0); 
cellStyle = wb.createCellStyle(); 
//指定单元格样式和值
cell.setCellStyle(cellStyle); 
cell.setCellValue(1);

3、sheet相关

//设置sheet名称
wb.setSheetName(0, "12" + "月合同到期");
//取得sheet的数目 
wb.getNumberOfSheets();
//新建名称为Output的sheet
HSSFSheet sheet = wb.createSheet("Output"); 
//根据index取得sheet对象
HSSFSheet sheet = wb.getSheetAt(0); 
//选中指定的工作表
sheet.setSelected(true);

4、有效的行,单元格个数

//取得有效的行数
int rowcount = sheet.getLastRowNum(); 
//取得一行的有效单元格个数
row.getLastCellNum();

5、单元格值类型读写

//根据单元格不同属性返回字符串数值
public String getCellStringValue(HSSFCell cell) { 
    String cellValue = ""; 
    switch (cell.getCellType()) { 
        case HSSFCell.CELL_TYPE_STRING://字符串类型 
            cellValue = cell.getStringCellValue(); 
            if(cellValue.trim().equals("")||cellValue.trim().length()<=0) {
                cellValue=" "; 
            }
            break; 
        case HSSFCell.CELL_TYPE_NUMERIC: //数值类型 
            cellValue = String.valueOf(cell.getNumericCellValue()); 
            break; 
        case HSSFCell.CELL_TYPE_FORMULA: //公式 
            cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); 
            cellValue = String.valueOf(cell.getNumericCellValue()); 
            break; 
        case HSSFCell.CELL_TYPE_BLANK: 
            cellValue=" "; 
            break; 
        case HSSFCell.CELL_TYPE_BOOLEAN: 
            break; 
        case HSSFCell.CELL_TYPE_ERROR: 
            break; 
        default: 
            break; 
    } 
    return cellValue; 
}


//设置单元格为STRING类型
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
//设置单元格的值---有重载
cell.setCellValue(value);
img

POI CellType类型有以下几种

CellType类型
CELL_TYPE_NUMERIC 数值型 0
CELL_TYPE_STRING 字符串型 1
CELL_TYPE_FORMULA 公式型 2
CELL_TYPE_BLANK 空值 3
CELL_TYPE_BOOLEAN 布尔型 4
CELL_TYPE_ERROR 错误 5

使用POI读取单元格的数据有两种方式:

  1. 通过setCellType将单元格类型设置为字符串,然后通过getRichStringCellValue读取该单元格数据,然后将读取到的字符串转换为对应的类型,
  2. 通过getCellType获取单元格类型,然后通过对应的getcellvalue方法读取该单元格数据,如:getNumericCellValue

6、设置列宽、行高

sheet.setColumnWidth((short)column,(short)width); 
row.setHeight((short)height);
//POI设置自适应列宽sheet.autoSizeColumn(i); (版本不能太老)
sheet.autoSizeColumn(i, true);(合并的单元格使用)
sheet.setColumnWidth(i, “列名”.getBytes().length*2*256);(中文适用)
公式单元格自适应的是公式,将值算出后再设置:
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet.getWorkbook());
CellValue cell71Val = evaluator.evaluate(cell71);
cell71.setCellValue(cell71Val.getNumberValue());
//调整单元格宽度 
sheet.setAutobreaks(true); 
sheet.setColumnWidth((short)i,colsWidth[i]); //设定单元格长度 
sheet.autoSizeColumn((short) i);//自动根据长度调整单元格长度

7、添加区域,合并单元格

//合并从第rowFrom行columnFrom列 
Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo ,(short)columnTo);
sheet.addMergedRegion(region);// 到rowTo行columnTo的区域 
// 获得一个 sheet 中合并单元格的数量
int sheetmergerCount = sheet.getNumMergedRegions();

8、常用单元格边框格式

HSSFCellStyle style = wb.createCellStyle(); 
style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框 
style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框 
style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框 
style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框

其中边框类型分为以下几种:

边框范例图 对应的静态值
img HSSFCellStyle. BORDER_DOTTED
img HSSFCellStyle. BORDER_HAIR
img HSSFCellStyle. BORDER_DASH_DOT_DOT
img HSSFCellStyle. BORDER_DASH_DOT
img HSSFCellStyle. BORDER_DASHED
img HSSFCellStyle. BORDER_THIN
img HSSFCellStyle. BORDER_MEDIUM_DASH_DOT_DOT
img HSSFCellStyle. BORDER_SLANTED_DASH_DOT
img HSSFCellStyle. BORDER_MEDIUM_DASH_DOT
img HSSFCellStyle. BORDER_MEDIUM_DASHED
img HSSFCellStyle. BORDER_MEDIUM
img HSSFCellStyle. BORDER_THICK
img HSSFCellStyle. BORDER_DOUBLE

9、设置字体和内容位置

HSSFFont font = wb.createFont();

font.setFontName("华文行楷");//设置字体名称
font.setFontHeightInPoints((short) 11);                    //字号 
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); //加粗 
font.setColor(HSSFColor.RED.index);               //设置字体颜色
font.setUnderline(FontFormatting.U_SINGLE);  //设置下划线
font.setTypeOffset(FontFormatting.SS_SUPER);//设置上标下标
font.setStrikeout(true);                                   //设置删除线
style.setFont(font); 

style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中 
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中 
style.setRotation(short rotation);//单元格内容的旋转的角度 
Style.setWrapText(true); //设置excel单元格中的内容换行
HSSFDataFormat df = wb.createDataFormat(); 
style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式 
cell.setCellStyle(style);

10、在工作单中清空行数据,调整行位置

HSSFWorkbook wb = new HSSFWorkbook(); 
HSSFSheet sheet = wb.createSheet("row sheet"); 
// Create various cells and rows for spreadsheet. 
// Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5) 
sheet.shiftRows(5, 10, -5);

11、填充和颜色设置

HSSFCellStyle style = wb.createCellStyle(); 
style.setFillBackgroundColor(HSSFColor.AQUA.index); 
style.setFillPattern(HSSFCellStyle.BIG_SPOTS); 
HSSFCell cell = row.createCell((short) 1); 
cell.setCellValue("X"); 
style = wb.createCellStyle(); 
style.setFillForegroundColor(HSSFColor.ORANGE.index); 
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); 
cell.setCellStyle(style);

12、工作表的放大缩小

sheet.setZoom(1,2); // 50 percent magnification 
sheet.setZoom(75); //75% scale

13. 使用公式

cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula("SUM(C2:C3)" ); //给单元格设公式 

14. 设置超链接

cell.setCellFormula("hyperlink(\"http://www.yiibai.com/testng/\",\"testng\")");

15、插入图片

public static void test1(){
    
    FileOutputStream fileOut = null;     
    BufferedImage bufferImg = null;     
   try {  
       ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();  
     //加载图片  
       bufferImg = ImageIO.read(new File(picture));     
       ImageIO.write(bufferImg, "jpg", byteArrayOut);  
       HSSFWorkbook wb = new HSSFWorkbook();     
       HSSFSheet sheet = wb.createSheet("sheet1");    
       
       HSSFPatriarch patriarch = sheet.createDrawingPatriarch();     
          HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)4,37);    
       //插入图片 1   
       patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));      
       //图片2  
       anchor = new HSSFClientAnchor(500, 0, 0, 0,(short) 5, 1, (short) 9, 38);  
       patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));  
       fileOut = new FileOutputStream( filepath+"/excel.xls");     
       // 输出文件   
        wb.write(fileOut);  
        System.out.println("test1");
   } catch (Exception e) {  
       e.printStackTrace();  
   }          
}  


public static void test3(){
    
    FileOutputStream fileOut = null;     
    BufferedImage bufferImg = null;     
   try {  
       ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();  
     //加载图片  
       bufferImg = ImageIO.read(new File(picture));     
       ImageIO.write(bufferImg, "jpg", byteArrayOut);  
       XSSFWorkbook wb = new XSSFWorkbook();     
       XSSFSheet sheet1 = wb.createSheet("sheet1");    
       XSSFDrawing drawing = sheet1.createDrawingPatriarch();     
          XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);          
       //插入图片 1   
          drawing.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));      
       fileOut = new FileOutputStream( filepath+ "/excel2.xlsx");     
       // 输出文件   
        wb.write(fileOut);  
        System.out.println("test3");
   } catch (Exception e) {  
       e.printStackTrace();  
   }          
}  

16. 从Excel文件提取图片

public static void testread(){
    InputStream inp;
    try {
        inp = new FileInputStream(filepath+"/excel.xls");
        HSSFWorkbook workbook = new HSSFWorkbook(inp);//读取现有的Excel文件
        List<HSSFPictureData> pictures = workbook.getAllPictures();
        for(int i=0;i<pictures.size();i++){
            HSSFPictureData pic=pictures.get(i);
            String ext = pic.suggestFileExtension();
            if (ext.equals("jpeg"))//判断文件格式,依照实际图片格式设置
            {
                FileOutputStream png=new FileOutputStream(filepath +"\\Apache.jpg");
                png.write(pic.getData());
                png.close();//保存图片
                System.out.println("test11");
            }
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK