0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何寫一個公用工具來進行Excel的導(dǎo)入導(dǎo)出

Android編程精選 ? 來源:Android編程精選 ? 作者:Android編程精選 ? 2022-10-09 14:19 ? 次閱讀

Part1序

日常在做后臺系統(tǒng)的時候會很頻繁的遇到Excel導(dǎo)入導(dǎo)出的問題,正好這次在做一個后臺系統(tǒng),就想著寫一個公用工具來進行Excel的導(dǎo)入導(dǎo)出。一般我們在導(dǎo)出的時候都是導(dǎo)出的前端表格,而前端表格同時也會對應(yīng)的在后臺有一個映射類。所以在寫這個工具的時候我們先理一下我們需要實現(xiàn)的效果:

導(dǎo)出方法接收一個list集合,和一個Class類型,和HttpServletResponse 對象

導(dǎo)出是可能會有下拉列表,所以需要一個map存儲下拉列表數(shù)據(jù)源,傳入參數(shù)后只需一行代碼即可導(dǎo)出

導(dǎo)入方法需要傳入file文件,以及一個Class類型,導(dǎo)入之后將會返回一個list集合,里面的對象就是傳入類型的對象,傳入?yún)?shù)后只需一行代碼即可導(dǎo)入

Part2實現(xiàn)過程

1.首先需要創(chuàng)建三個注解

一個是EnableExport ,必須有這個注解才能導(dǎo)出

/**
*設(shè)置允許導(dǎo)出
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceEnableExport{
StringfileName();

}

然后就是EnableExportField,有這個注解的字段才會導(dǎo)出到Excel里面,并且可以設(shè)置列寬

/**
*設(shè)置該字段允許導(dǎo)出
*并且可以設(shè)置寬度
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceEnableExportField{
intcolWidth()default100;
StringcolName();
}

再就是ImportIndex,導(dǎo)入的時候設(shè)置Excel中的列對應(yīng)的序號

/**
*導(dǎo)入時索引
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceImportIndex{
intindex();


}

注解使用示例

3bef6c88-4574-11ed-96c9-dac502259ad0.png三個注解創(chuàng)建好之后就需要開始操作Excel了

Part3操作Excel

首先,導(dǎo)入方法。在后臺接收到前端上傳的Excel文件之后,使用poi來讀取Excel文件我們根據(jù)傳入的類型上面的字段注解的順序來分別為不同的字段賦值,然后存入集合中,再返回

歡迎關(guān)注公眾號"Java學(xué)習(xí)之道",查看更多干貨!

代碼如下:

/**
*將Excel轉(zhuǎn)換為對象集合
*@paramexcelExcel文件
*@paramclazzpojo類型
*@return
*/
publicstaticListparseExcelToList(Fileexcel,Classclazz){
Listres=newArrayList<>();
//創(chuàng)建輸入流,讀取Excel
InputStreamis=null;
Sheetsheet=null;
try{
is=newFileInputStream(excel.getAbsolutePath());
if(is!=null){
Workbookworkbook=WorkbookFactory.create(is);
//默認只獲取第一個工作表
sheet=workbook.getSheetAt(0);
if(sheet!=null){
//前兩行是標(biāo)題
inti=2;
Stringvalues[];
Rowrow=sheet.getRow(i);
while(row!=null){
//獲取單元格數(shù)目
intcellNum=row.getPhysicalNumberOfCells();
values=newString[cellNum];
for(intj=0;j<=?cellNum;?j++)?{
????????????????????????Cell?cell?=???row.getCell(j);
????????????????????????if?(cell?!=?null)?{
????????????????????????????//設(shè)置單元格內(nèi)容類型
????????????????????????????cell.setCellType(Cell.CELL_TYPE_STRING?);
????????????????????????????//獲取單元格值
????????????????????????????String?value?=?cell.getStringCellValue()?==?null???null?:?cell.getStringCellValue();
????????????????????????????values[j]=value;
????????????????????????}
????????????????????}
????????????????????Field[]?fields?=?clazz.getDeclaredFields();
????????????????????Object?obj?=?clazz.newInstance();
????????????????????for(Field?f?:?fields){
????????????????????????if(f.isAnnotationPresent(ImportIndex.class)){
????????????????????????????ImportIndex?annotation?=?f.getDeclaredAnnotation(ImportIndex.class);
????????????????????????????int?index?=?annotation.index();
????????????????????????????f.setAccessible(true);
????????????????????????????//此處使用了阿里巴巴的fastjson包里面的一個類型轉(zhuǎn)換工具類
????????????????????????????Object?val?=TypeUtils.cast(values[index],f.getType(),null);
????????????????????????????f.set(obj,val);
????????????????????????}
????????????????????}
????????????????????res.add(obj);
????????????????????i++;
????????????????????row=sheet.getRow(i);
????????????????}

????????????}
????????}
????}?catch?(Exception?e)?{
????????e.printStackTrace();
????}
????return?res;
}

接下來就是導(dǎo)出方法

導(dǎo)出分為幾個步驟:

1 建立一個工作簿,也就是類型新建一個Excel文件

3c1fdefe-4574-11ed-96c9-dac502259ad0.png

2 建立一張sheet表

3c3801dc-4574-11ed-96c9-dac502259ad0.png

3 設(shè)置標(biāo)的行高和列寬

3c4eb008-4574-11ed-96c9-dac502259ad0.png

4 繪制標(biāo)題和表頭

3c6b1860-4574-11ed-96c9-dac502259ad0.png這兩個方法是自定義方法,代碼會貼在后面

5 寫入數(shù)據(jù)到Excel

3c913e5a-4574-11ed-96c9-dac502259ad0.png

6 創(chuàng)建下拉列表

3cb8b2be-4574-11ed-96c9-dac502259ad0.png

7 寫入文件到response

3cd36c44-4574-11ed-96c9-dac502259ad0.png到這里導(dǎo)出工作就完成了下面是一些自定義方法的代碼

歡迎關(guān)注公眾號"Java學(xué)習(xí)之道",查看更多干貨!

/**
*獲取一個基本的帶邊框的單元格
*@paramworkbook
*@return
*/
privatestaticHSSFCellStylegetBasicCellStyle(HSSFWorkbookworkbook){
HSSFCellStylehssfcellstyle=workbook.createCellStyle();
hssfcellstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
hssfcellstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
hssfcellstyle.setWrapText(true);
returnhssfcellstyle;
}

/**
*獲取帶有背景色的標(biāo)題單元格
*@paramworkbook
*@return
*/
privatestaticHSSFCellStylegetTitleCellStyle(HSSFWorkbookworkbook){
HSSFCellStylehssfcellstyle=getBasicCellStyle(workbook);
hssfcellstyle.setFillForegroundColor((short)HSSFColor.CORNFLOWER_BLUE.index);//設(shè)置背景色
hssfcellstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
returnhssfcellstyle;
}

/**
*創(chuàng)建一個跨列的標(biāo)題行
*@paramworkbook
*@paramhssfRow
*@paramhssfcell
*@paramhssfsheet
*@paramallColNum
*@paramtitle
*/
privatestaticvoidcreateTitle(HSSFWorkbookworkbook,HSSFRowhssfRow,HSSFCellhssfcell,HSSFSheethssfsheet,intallColNum,Stringtitle){
//在sheet里增加合并單元格
CellRangeAddresscra=newCellRangeAddress(0,0,0,allColNum);
hssfsheet.addMergedRegion(cra);
//使用RegionUtil類為合并后的單元格添加邊框
RegionUtil.setBorderBottom(1,cra,hssfsheet,workbook);//下邊框
RegionUtil.setBorderLeft(1,cra,hssfsheet,workbook);//左邊框
RegionUtil.setBorderRight(1,cra,hssfsheet,workbook);//有邊框
RegionUtil.setBorderTop(1,cra,hssfsheet,workbook);//上邊框

//設(shè)置表頭
hssfRow=hssfsheet.getRow(0);
hssfcell=hssfRow.getCell(0);
hssfcell.setCellStyle(getTitleCellStyle(workbook));
hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING);
hssfcell.setCellValue(title);
}

/**
*設(shè)置表頭標(biāo)題欄以及表格高度
*@paramworkbook
*@paramhssfRow
*@paramhssfcell
*@paramhssfsheet
*@paramcolNames
*/
privatestaticvoidcreateHeadRow(HSSFWorkbookworkbook,HSSFRowhssfRow,HSSFCellhssfcell,HSSFSheethssfsheet,ListcolNames){
//插入標(biāo)題行
hssfRow=hssfsheet.createRow(1);
for(inti=0;iselectListMap){
if(selectListMap!=null){
selectListMap.forEach(
//第幾列校驗(0開始)key數(shù)據(jù)源數(shù)組value
(key,value)->{
if(value.length>0){
CellRangeAddressListcellRangeAddressList=newCellRangeAddressList(2,65535,key,key);
DataValidationHelperhelper=sheet.getDataValidationHelper();
DataValidationConstraintconstraint=helper.createExplicitListConstraint(value);
DataValidationdataValidation=helper.createValidation(constraint,cellRangeAddressList);
//處理Excel兼容性問題
if(dataValidationinstanceofXSSFDataValidation){
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
}else{
dataValidation.setSuppressDropDownArrow(false);
}
dataValidation.setEmptyCellAllowed(true);
dataValidation.setShowPromptBox(true);
dataValidation.createPromptBox("提示","只能選擇下拉框里面的數(shù)據(jù)");
sheet.addValidationData(dataValidation);
}
}
);
}
}

Part4使用實例

導(dǎo)出數(shù)據(jù)

3d06dd9a-4574-11ed-96c9-dac502259ad0.png

導(dǎo)入數(shù)據(jù)(返回對象List)

3d33a7a8-4574-11ed-96c9-dac502259ad0.png

審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Excel
    +關(guān)注

    關(guān)注

    4

    文章

    215

    瀏覽量

    55361
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4670

    瀏覽量

    67764
  • 數(shù)據(jù)源
    +關(guān)注

    關(guān)注

    1

    文章

    61

    瀏覽量

    9639

原文標(biāo)題:利用Java注解+反射優(yōu)雅的實現(xiàn)通用Excel導(dǎo)入導(dǎo)出

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    在LabVIEW中導(dǎo)入導(dǎo)出Excel文件程序設(shè)計

    LabVIEW Report Generation工具包的基礎(chǔ)上,以示例方式描述了在LabVIEW開發(fā)環(huán)境中利用報表生成器函數(shù),實現(xiàn)導(dǎo)入Excel文件和導(dǎo)出
    發(fā)表于 10-25 14:58

    labview如何導(dǎo)入導(dǎo)出Excel表,希望能給示例或者模板參考!

    labview如何導(dǎo)入導(dǎo)出Excel表,希望能給示例或者模板參考!比較急在做課設(shè)?。?/div>
    發(fā)表于 11-12 16:57

    如何寫簡易的printf函數(shù)?

    如何寫簡易的printf函數(shù)?
    發(fā)表于 04-28 06:47

    module 概述以及如何寫module

    driver,而且它也能縮短我們 driver development 的時間。在這篇文章里,我將要跟各位介紹下 module 的原理,以及如何寫 module。 module
    發(fā)表于 11-07 11:37 ?0次下載

    如何寫簡短的Python代碼做一個換臉程序的詳細概述

    在這篇文章中將介紹如何寫簡短(200行)的 Python 腳本,來自動地將幅圖片的臉替換為另幅圖片的臉。
    的頭像 發(fā)表于 07-09 10:48 ?4412次閱讀

    如何用公用工具進行Excel導(dǎo)入導(dǎo)出

    日常在做后臺系統(tǒng)的時候會很頻繁的遇到Excel導(dǎo)入導(dǎo)出的問題,正好這次在做一個后臺系統(tǒng),就想著
    的頭像 發(fā)表于 08-20 09:33 ?2643次閱讀
    如何用<b class='flag-5'>一</b><b class='flag-5'>個</b><b class='flag-5'>公用工具</b><b class='flag-5'>來</b><b class='flag-5'>進行</b><b class='flag-5'>Excel</b>的<b class='flag-5'>導(dǎo)入</b><b class='flag-5'>導(dǎo)出</b>

    公用工具進行Excel導(dǎo)入導(dǎo)出

    導(dǎo)入方法需要傳入file文件,以及Class類型,導(dǎo)入之后將會返回list集合,里面的對
    的頭像 發(fā)表于 06-01 10:48 ?1650次閱讀

    如何使用 Python 創(chuàng)建些強大的應(yīng)用和實用工具

    本文將探討如何以 Zynq UltraScale 器件上的 IP 核為目標(biāo),使用 Python 創(chuàng)建些強大的應(yīng)用和實用工具。此處提供了
    發(fā)表于 09-08 10:23 ?631次閱讀

    百萬數(shù)據(jù)的導(dǎo)入導(dǎo)出解決方案

    就是從DB中查詢數(shù)據(jù)然后使用POI寫到Excel上。 寫本文的背景是因為在工作中遇到了大數(shù)據(jù)的導(dǎo)入導(dǎo)出,問題既然來了逃跑不如干掉它?。?! 只要這次解決了,后期遇到同樣的問題就好解決
    的頭像 發(fā)表于 10-11 17:19 ?1195次閱讀

    如何導(dǎo)入導(dǎo)出SCL源文件?

    如何導(dǎo)入導(dǎo)出SCL源文件?
    的頭像 發(fā)表于 01-16 10:41 ?1954次閱讀

    excel導(dǎo)出功能如何實現(xiàn)?

    最近我做過MySQL`百萬級別`數(shù)據(jù)的`excel`導(dǎo)出功能,已經(jīng)正常上線使用了。 這個功能挺有意思的,里面需要注意的細節(jié)還真不少,現(xiàn)在拿出來跟大家分享
    的頭像 發(fā)表于 05-11 18:17 ?1116次閱讀
    <b class='flag-5'>excel</b><b class='flag-5'>導(dǎo)出</b>功能如何實現(xiàn)?

    款解決大文件內(nèi)存溢出的 Excel 處理工具

    ? 介紹 快速開始 引入依賴 簡單導(dǎo)出 定義實體類 復(fù)雜導(dǎo)出 簡單導(dǎo)入 參考資料 介紹 EasyExcel 是基于 Java 的、快速、
    的頭像 發(fā)表于 07-03 16:11 ?1556次閱讀
    <b class='flag-5'>一</b>款解決大文件內(nèi)存溢出的 <b class='flag-5'>Excel</b> 處理<b class='flag-5'>工具</b>

    如何寫簡單的裝飾器

    要的是,它讓 Python 中被裝飾器裝飾后的方法長得更像裝飾前的方法。 本篇文章不會過多的向你介紹裝飾器的基本知識,我會默認你知道什么是裝飾器,并且懂得如何寫簡單的裝飾器。 不了解裝飾器的可以先去閱讀我之前
    的頭像 發(fā)表于 11-01 09:54 ?400次閱讀
    <b class='flag-5'>如何寫</b><b class='flag-5'>一</b><b class='flag-5'>個</b>簡單的裝飾器

    如何寫內(nèi)存泄漏檢測工具

    如何確定有內(nèi)存泄露問題,如何定位到內(nèi)存泄露位置,如何寫內(nèi)存泄漏檢測工具? 1:概述 內(nèi)存泄露本質(zhì):其實就是申請調(diào)用malloc/new,但是釋放調(diào)用free/delete有遺漏,或
    的頭像 發(fā)表于 11-11 16:19 ?708次閱讀

    數(shù)據(jù)庫的clob類型如何導(dǎo)入導(dǎo)出

    導(dǎo)入導(dǎo)出操作時,可以使用不同的方法和工具實現(xiàn),具體取決于數(shù)據(jù)庫的類型和版本。 導(dǎo)出CL
    的頭像 發(fā)表于 11-21 10:51 ?3914次閱讀