【開源庫推薦】#4 Poi-辦公文檔處理庫

来源:https://www.cnblogs.com/stars-one/archive/2022/12/08/16966037.html
-Advertisement-
Play Games

原文:【開源庫推薦】 #4 Poi-辦公文檔處理庫 - Stars-One的雜貨小窩 github倉庫apache/poi Apache POI是Apache軟體基金會的開放源碼函式庫,POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。.NET的開發人員則可以利用 ...


原文:【開源庫推薦】 #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()

效果:

讀寫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

其中邊框類型分為以下幾種:

邊框範例圖 對應的靜態值
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();
    }
}

參考


提問之前,請先看提問須知 點擊右側圖標發起提問 聯繫我 或者加入QQ群一起學習 Stars-One安卓學習交流群 TornadoFx學習交流群:1071184701
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要介紹Java8新特性之Optional類,分別介紹了獲取對象的3個方法、獲取數值的3個方法、處理數值的2個方法、映射數值的1個方法以及實際應用。 ...
  • Java18(2022.3) 將 UTF-8 指定為標準 Java API 的預設字元集 提供支持靜態文件的最小 Web 伺服器命令行工具jwebserver 定義了一個全新的 SPI(service-provider interface),用於主要名稱和地址的解析 棄用 Finalization ...
  • 微信(WeChat)是騰訊公司於2011年1月21日推出的一款社交軟體,8年時間微信做到日活10億,日消息量450億。在此期間微信也推出了不少的功能如:“搖一搖”、“漂流瓶”、“朋友圈”、“附近的人”、“公眾平臺”、“小程式”等等,涵蓋了我們生活的方方面面,微信正在慢慢踐行著他們的口號:微信,是一種 ...
  • C++11 函數對象的升級版=>lambda表達式 函數對象的缺點: 使用在泛型演算法,參數傳遞, 比較性質/自定義操作 優先順序隊列, 需要專門定義出一個類 //lambda表達式語法: //[捕獲外部變數](形參列表)->返回值{操作代碼} auto func1=[]()->void{cout<<" ...
  • 主角:takewhile 判斷序列中元素是否為偶數,奇數則終止 這是我們最常用的一種方式,其實沒必要這麼複雜 1 a = [4, 6, 7, 3] 2 3 4 def judge_is_even(item): 5 if item % 2 == 0: 6 return True 7 return Fa ...
  • 1 編譯器分類 Java的編譯過程:將源代碼轉化成機器可執行的二進位代碼。實際上,編譯過程,是分階段進行的,由此產生了不同的編譯器。 編譯器分類: | 類別 | 工作內容 | 代表 | | | | | | 前端編譯器 | 把源代碼轉變成位元組碼 | JDK的Javac、Eclipse編譯器(ECJ) ...
  • bind1st和bind2nd只能用於二元函數對象 c++11 bind綁定器 返回的結果還是個函數對象 std::bind函數定義在頭文件functional中,是一個函數模板,它就像一個函數適配器,接受一個可調用對象(callable object),生成一個新的可調用對象來“適應”原對象的參數 ...
  • 1. time模塊 import time *一*#時間戳--》結構化時間--》格式化的字元串時間 res1=time.localtime(654126574) print(res1 ) #res1 time.struct_time(tm_year=1990, tm_mon=9, tm_mday=2 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...