使用Easyexcel實現不同場景的數據導出功能
導出的數據包含有圖片
導出excel表格的數據包含有圖片,這種場景比較少。通Easyexcel實現這樣的需求,我認為最簡便的方法就是使用前面提到的自定義轉換器(com.alibaba.excel.converters.Converter);假如有這樣一個場景,導出員工的信息,還要包括員工的一寸照。通常情況下,數據庫并不會真的存一張圖片,而是圖片存儲位置的相對路徑。
1、新建一個類EmpHeadPhotoConverter,實現com.alibaba.excel.converters.Converter接口,并重寫convertToExcelData()方法;
2、在重寫convertToExcelData()方法中,根據圖片的相同路徑或網絡地址讀取出圖片的字節(jié)流作為構建WriteCellData對象的參數然后返回;
3、在員工信息的實體類Employee的照片列引入自定義的類型轉換器(EmpHeadPhotoConverter)
4、使用EasyExcel的工廠方法把數據寫出到excel表格中;
注:這里是使用默認的樣式,所以看起來可能點丑;@ContentRowHeight()用于調節(jié)數據行的高度;@ColumnWidth用于調節(jié)數據列的寬度;
public class EmpHeadPhotoConverter implements Converter<String> {
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
//根據圖片的相對路徑或網絡地址讀取圖片到byte輸出流(ByteArrayOutputStream)
ByteArrayOutputStream byteArrayOutputStream = null;
InputStream inputStream=null;
try {
inputStream = ClassLoader.getSystemResourceAsStream(value);
byteArrayOutputStream = new ByteArrayOutputStream();
int len=-1;
byte[] bytes = new byte[1024];
while ((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
}
//把輸出流中的圖片字節(jié)數組作為參數構建writeCellData對象并返回
//WriteCellData是EasyExcel對單元格數據的封裝
return new WriteCellData<>(byteArrayOutputStream.toByteArray());
}
}
@Data
@ContentRowHeight(50)//數據行的高度
public class Employee implements Serializable {
@ExcelProperty("姓名")
private String realName;
@ExcelProperty("員工編號")
private String empNo;
@ExcelProperty("性別")
private String sex;
@ExcelProperty("家庭地址")
private String address;
@ExcelProperty("聯系電話")
private String phone;
@ExcelProperty("電子郵箱")
private String email;
@ExcelProperty(value = "照片",converter = EmpHeadPhotoConverter.class)
@ColumnWidth(10)//列寬
private String headPhoto;
}
@Test
public void writeImage(){
String exportPath=this.getExportPath();
String exportFile=exportPath+File.separator+"員工基本信息(包含照片).xlsx";
List<Employee> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Employee employee = new Employee();
employee.setRealName("張三"+i);
employee.setEmpNo("CH"+(i+1));
employee.setAddress("北京");
employee.setEmpNo("zhangsan@163.com");
employee.setSex("女");
employee.setPhone("17777xxxxxx");
//這里是示例,因為我把示例圖片放在了classpath下,后面可以根據圖片名字在classpath下找到
//在實際的業(yè)務開發(fā)過程中,這里應該是圖片的相對路徑或網絡地址
employee.setHeadPhoto("zhangsan.jpeg");
list.add(employee);
}
EasyExcel.write(exportFile,Employee.class).sheet().doWrite(list);
}

導出表格指定列寬行高
上面其實是已經說過了,通過注解可以簡單的指定導出Excel表格的行、列的高度和寬度:
@ContentRowHeight()用于指定數據行的高度;
@HeadRowHeight()用于指定表頭行的高度;
@ColumnWidth()用于指定數據列的寬度;
導出表格自定義樣式
我比較喜歡使用easyexcel的一個很重要的原因就是,easyexcel在poi的基礎上,封裝的比較友好。就比如,在導出的時候,很多情況下需要自定義表格的樣式,easyexcel就提供了多種的實現方式。主要有三種:
1、通過注解;
2、編程式;
3、自定義類型轉換器。
不同的方式,側重的場景也有所不同,下面通過示例梳理一下使用方法:
編程式自定義樣式
通過編程式來自定義導出表格的樣式中,有一個非常關鍵類HorizontalCellStyleStrategy。
1、通過HorizontalCellStyleStrategy可以配置好表頭的樣式和數據行的樣式;
2、使用Easyexcel的工廠方法寫出數據前,把通過HorizontalCellStyleStrategy構建好的樣式策略注冊到表格寫出構建器里;
3、使用使用Easyexcel的工廠方法寫出數據;
總結:這種方法的優(yōu)點就是比較簡單,且容易理解構建樣式的過程;缺點就是不太靈活;比較適合那些導出表格前可以明確知道導出的表格的樣式特點;
@Test
public void writeWithStyle2() {
String exportPath = this.getExportPath();
String exportFile = exportPath + File.separator + "員工基本信息v2.xlsx";
List<Employee> list = new ArrayList<>();
Employee employee = new Employee();
employee.setRealName("張三");
employee.setEmpNo("CH001");
employee.setSex("女");
Employee employee2 = new Employee();
employee2.setRealName("李四");
employee2.setEmpNo("CH002");
employee2.setSex("男");
list.add(employee);
list.add(employee2);
// 頭的策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 背景設置為紅色
headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short)20);
headWriteCellStyle.setWriteFont(headWriteFont);
// 內容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 這里需要指定 FillPatternType 為FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認了 FillPatternType所以可以不指定
contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
// 背景綠色
contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
WriteFont contentWriteFont = new WriteFont();
// 字體大小
contentWriteFont.setFontHeightInPoints((short)20);
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 這個策略是 頭是頭的樣式 內容是內容的樣式 其他的策略可以自己實現
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉
EasyExcel.write(exportFile, Employee.class)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet()
.doWrite(list);
}
注解形式自定義樣式
通過注解的形式來自定義導出表格的樣式,和編程式的比較類似,明顯的區(qū)別是一個需要通過在編寫代碼來定義樣式并應用這個樣式;另一個是需要 使用注解定義好表格樣式,應用樣式的過程easyexcel內部已經實現了,不用自己編寫代碼來實現??傮w上特點是一樣的:使用簡單,且比較好理解,缺點就是不靈活,不能動態(tài)的設置導出表格內單元格的樣式。比較常用的注解有以下(有的是作用在類上,有的是作用在屬性上,注解需要設置哪些屬性可以點以注解的源里一看就很清楚):
作用在類上:
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10) // 頭字體設置成20 @HeadFontStyle(fontHeightInPoints = 20) // 內容的背景設置成綠色 IndexedColors.GREEN.getIndex() @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17) // 內容字體設置成20 @ContentFontStyle(fontHeightInPoints = 20)
作用在屬性上
// 字符串的頭背景設置成粉紅 IndexedColors.PINK.getIndex() @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14) // 字符串的頭字體設置成20 @HeadFontStyle(fontHeightInPoints = 30) // 字符串的內容的背景設置成天藍 IndexedColors.SKY_BLUE.getIndex() @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40) // 字符串的內容字體設置成20 @ContentFontStyle(fontHeightInPoints = 30)
自定義類型轉換器形式定義樣式
前兩種的樣式定義方法,都比較固定,不能根據導出數據的規(guī)則來動態(tài)設置表格內單元格的樣式,如導出員工信息表格里如果性別是女的員工數據行,則使用紅色字體,如果是男性,則是使用藍色;因為導出數據通常是從數據源里動態(tài)取出的,在導出前沒辦法確定哪些行是男性,哪些員工是女性,所以需要動態(tài)的設置導出表格的樣式,自定義類型轉換器就可以很好的解決這個問題。
1、新建一個類SexColourConverter,實現com.alibaba.excel.converters.Converter接口,并重寫convertToExcelData()方法;
2、重寫convertToExcelData()方法中,根據單元格的內容設置不同的樣式,示例中:如果性別是男,則字體為藍色;如果性別是女,則字體顏色是紅色;
3、在員工信息的實體類Employee的性別(sex)屬性上,通過@ExcelProperty()引入自定義的類型轉換器SexColourConverter;
4、使用Easyexcel的工廠方法實現表格數據的寫出;
總結:這種方法很靈活,非常適合一些報表中,要求導出表格中數據達到在不同規(guī)則就要求有不同的樣式的場景。在我做過的項目里,有不少導出都有類似的規(guī)則:某個屬性達到預警閾值時,要導出數據的單元格格式標成紅色。
public class SexColourConverter implements Converter<String> {
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
WriteCellStyle writeCellStyle = new WriteCellStyle();
WriteFont writeFont = new WriteFont();
if ("男".equals(value)) {
writeFont.setColor((short) 12);
}
if ("女".equals(value)) {
writeFont.setColor((short) 10);
}
writeCellStyle.setWriteFont(writeFont);
WriteCellData<Object> cellData = new WriteCellData<>();
cellData.setWriteCellStyle(writeCellStyle);
cellData.setType(CellDataTypeEnum.STRING);
cellData.setStringValue(value);
return cellData;
}
}@Data
public class Employee implements Serializable {
@ExcelProperty("姓名")
private String realName;
@ExcelProperty("員工編號")
private String empNo;
@ExcelProperty(value = "性別",converter = SexColourConverter.class)
private String sex;
}
@Test
public void writeWithStyle() {
String exportPath = this.getExportPath();
String exportFile = exportPath + File.separator + "員工基本信息v2.xlsx";
List<Employee> list = new ArrayList<>();
Employee employee = new Employee();
employee.setRealName("張三");
employee.setEmpNo("CH001");
employee.setSex("女");
Employee employee2 = new Employee();
employee2.setRealName("李四");
employee2.setEmpNo("CH002");
employee2.setSex("男");
list.add(employee);
list.add(employee2);
EasyExcel.write(exportFile, Employee.class).sheet().doWrite(list);
}在設置單元格背景或字體的顏色的時候,顏色會對應一個short類型的數據
復雜表頭的導出
特別是一些財務類型的報表導出,表頭往往是復合表頭,比較復雜
easyexcel對于這種場景提供了兩種方法,一種是注解;另外一種是通過一種特殊的數據結構List<list>;根據我的感受,我是推薦使用注解的;
第一種:
如果是所在列是復合表頭,則使用@ExcelProperty()注解,從上到下標明表頭組成;如果是普通表頭,按普通的用法標明表頭名稱即可;是不是很簡單?
@Data
public class EmpSalary {
@ExcelProperty({"基本信息","姓名"})
private String realName;
@ExcelProperty({"基本信息","員工編號"})
private String empNo;
//,converter = SalaryDateConverter.class
@ExcelProperty(value = "工資日期")
private String salaryDate;
@ExcelProperty({"工資構成","基本工資"})
private Float baseAmount;
@ExcelProperty({"工資構成","全勤獎"})
private Float fullAttendAmount;
@ExcelProperty({"工資構成","五險一金"})
private Float insurance;
//特別資金
@ExcelIgnore
private Float specialAmount;
}@Test
public void writeHead() {
String exportPath = this.getExportPath();
String exportFile = exportPath + File.separator + "員工工資表v3.xlsx";
EasyExcel.write(exportFile, EmpSalary.class).sheet().doWrite(this.empSalaryData(10));
}
第二種:
使用List<list>結構來組織表頭數據,開始的時候還不是很理解表頭的數據結構為什么這么奇怪,到這里是不是明白了。對于普通表頭List肯定就可以了,但是在一些復雜的場景就不行了。這么制定的話,什么場景都不在話下,關鍵還可以動態(tài)生成表頭,這一點確實比注解的方式要靈活一些;所以具體使用哪種,要根據業(yè)務場景決定了。
@Test
public void writeHead() {
String exportPath = this.getExportPath();
String exportFile = exportPath + File.separator + "員工工資表v4.xlsx";
List<List<String>> headList = new ArrayList<>();
List<String> head1 = new ArrayList<>();
head1.add("基本信息");
head1.add("姓名");
headList.add(head1);
List<String> head2 = new ArrayList<>();
head2.add("基本信息");
head2.add("員工編號");
headList.add(head2);
List<String> head3 = new ArrayList<>();
head3.add("工資日期");
headList.add(head3);
List<String> head4 = new ArrayList<>();
head4.add("工資構成");
head4.add("基本工資");
headList.add(head4);
List<String> head5 = new ArrayList<>();
head5.add("工資構成");
head5.add("全勤獎");
headList.add(head5);
List<String> head6 = new ArrayList<>();
head6.add("工資構成");
head6.add("保險");
headList.add(head6);
EasyExcel.write(exportFile).head(headList).sheet().doWrite(this.empSalaryData(10));
}日期、數字、自定義格式的導出
自定義格式的導出可以參考上一篇《Spring Boot:基于Easyexcel實現導入功能》中的日期、數字及其他自定義格式的轉換部分,SalaryDateConverter#convertToExcelData(),導出時候的數據格式轉換邏輯可以寫在這里面;SalaryDateConverter#convertToJavaData()導入時候的數據格式轉換的實現邏輯可以寫在這里;SalaryDateConverter是com.alibaba.excel.converters.Converter的實現類;
除了實現com.alibaba.excel.converters.Converterr接口,easyexcel也預置了一些常用的注解來實現格式轉換,導入導出的時候都能用,如@DateTimeFormat、@NumberFormat;
這里特別注意別導錯類了:
com.alibaba.excel.annotation.format.DateTimeFormat;
com.alibaba.excel.annotation.format.NumberFormat;
@Data
public class EmpSalary {
@ExcelProperty({"基本信息","姓名"})
private String realName;
@ExcelProperty({"基本信息","員工編號"})
private String empNo;
@DateTimeFormat("yyyy年MM月")
@ExcelProperty(value = "工資日期")
private Date salaryDate;
@ExcelProperty({"工資構成","基本工資"})
private Float baseAmount;
@ExcelProperty({"工資構成","全勤獎"})
private Float fullAttendAmount;
@ExcelProperty({"工資構成","五險一金"})
private Float insurance;
//特別資金
@ExcelIgnore
@NumberFormat
private Float specialAmount;
@NumberFormat("#.##%")
@ExcelProperty("績效完成百分比")
private Double jixiao;
}@Test
public void writeByConverter(){
String exportPath = this.getExportPath();
String exportFile = exportPath + File.separator + "員工工資表v5.xlsx";
List<EmpSalary> list=new ArrayList<>();
EmpSalary empSalary = new EmpSalary();
empSalary.setEmpNo("CH" + ( 1));
empSalary.setRealName("張三" + ( 1));
empSalary.setSalaryDate(new Date());
empSalary.setBaseAmount(5000f);
empSalary.setFullAttendAmount(500f);
empSalary.setInsurance(300f);
empSalary.setJixiao(0.9877);
list.add(empSalary);
EasyExcel.write(exportFile, EmpSalary.class).sheet("12月").doWrite(list);
}讀取全部的sheet頁
這里需要注意兩個地方:1、讀取shee頁的數據結構是一樣的;2、excel的列與接收數據類的屬性是一一對應的,如果不對應,可參考讀取到指定列部分,使用@ExcelProperty(index=xx)顯性的指定對應關系;
@Data
public class Student implements Serializable {
private Integer id;
private String stuCode;
private String stuName;
private String sex;
private String born;
private Integer age;
private String address;
private String motherName;
private String fatherName;
private Integer grade;
private Integer classNum;
}
@Test
public void readAllSheet(){
String userDir = System.getProperty("user.dir");
String importPath = userDir + File.separator + "import";
File dir = new File(importPath);
if (!dir.exists()) {
dir.mkdirs();
}
String importFile = importPath + File.separator + "學生信息表.xlsx";
StudentReadListener studentReadListener = new StudentReadListener();
EasyExcel.read(importFile, Student.class, studentReadListener).doReadAll();
List<Student> students = studentReadListener.getStudents();
for (Student student : students) {
System.out.println(student.getStuName());
}
}日期、數字及其他自定義格式的轉換
在導入或者導出excel的時候,如果想對某一列的數據格式作調整轉換,可以自定義一個轉換器(com.alibaba.excel.converters.Converter),然后這個個轉換器通過@ExcelProperty(converter=xxxxx.class)標記在接收參數的類型的屬性上;
這種轉換數據格式的需求,有時候是主動的,有時候是被動的。什么是主動的的呢?假如前數據為庫存儲的日期格式是yyyyMMdd,導出的時候想要的是xxxx年xx月xx日,然后你就可以實現一個類型轉換器(Converter)主動完成這個事。下面舉個被動的例子,excel中關于日期的一個坑,繞不過的坑,所以是“被動”滴。
excel中單元格式格式是日期的,easyexcel解析后是一個數字,這不是解析錯誤了,而是excel中對于日期存儲的格式就是數字,這個數字代表的是1900年1月1日,到單元格式內日期的天數,所以解析結果中是一個數字并不難理解,但是這不是我我們想要的結果呀。更惡心的是,java中的Date的時間起點1970年1月1日,所以被動的需求就產生了,需要把一個以1900-1-1為起天的天數代表的日期,轉換為以1970-1-1為起點的java.util.Date。標準的不統(tǒng)一,產生的結果就是這么惡心。
public class SalaryDateConverter implements Converter<String> {
@Override
public Class<?> supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
//導入的時候會走這個方法,導入的轉換邏輯可以在這個方法里實現
@Override
public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
BigDecimal numberValue = cellData.getNumberValue();
//平時不要動不動就搞個util工具類,我曾經目睹一個新同事,用上用不上的也不管,上來在工程里導入了幾十個工具類,搞得maven依賴沖突
// org.apache.poi.ss.usermodel.DateUtil是POI的工具類,
// DateUtil.getJavaDate()的功能就是把以1900-1-1為起點的日期天數轉換成java.util.Date,直接拿來用就好了,基本不用擔心里面有bug
Date javaDate = DateUtil.getJavaDate(numberValue.doubleValue());
//com.alibaba.excel.util.DateUtils是easyexcel封裝的日期轉換工具類,能用就用上唄,基本也不用擔心有bug
String format = DateUtils.format(javaDate, DateUtils.DATE_FORMAT_10);
return format;
}
//導出的時候會走這個方法,導出的轉換邏輯可以在這個方法里實現
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return null;
}
}@Data
public class EmpSalary {
@ExcelProperty("姓名")
private String realName;
@ExcelProperty("員工編號")
private String empNo;
@ExcelProperty(value = "工資日期",converter = SalaryDateConverter.class)
private String salaryDate;
@ExcelProperty("工資數額")
private Float amount;
}
@Test
public void readByConvert(){
String userDir = System.getProperty("user.dir");
String importPath = userDir + File.separator + "import";
File dir = new File(importPath);
if (!dir.exists()) {
dir.mkdirs();
}
String importFile = importPath + File.separator + "員工工資表.xlsx";
EmpSalaryReadListener empSalaryReadListener = new EmpSalaryReadListener();
EasyExcel.read(importFile, EmpSalary.class, empSalaryReadListener).sheet().doRead();
List<EmpSalary> empSalaries = empSalaryReadListener.getEmpSalaries();
System.out.println(empSalaries.size());
}表頭有多行的讀取
easyexcel在讀取表格內容的時候,默認是從第二行開始讀的,因為第一行通常是表頭,所以上面沒有指定從第幾行開始讀也沒有問題。但是遇到下圖樣式的復合表頭的時候,表頭是占了兩行,數據是從第三行開始的,那么在讀取的時候讀取監(jiān)聽器、接收數據的類沒有變化,而是在讀取的時候要顯性指定從第幾行開始讀,實際指定的時候是索引,從0開始,第三行的索引就是2;

@Test
public void readManyRow(){
String userDir = System.getProperty("user.dir");
String importPath = userDir + File.separator + "import";
File dir = new File(importPath);
if (!dir.exists()) {
dir.mkdirs();
}
String importFile = importPath + File.separator + "員工工資表 - 副本.xlsx";
EmpSalaryReadListener empSalaryReadListener = new EmpSalaryReadListener();
//數據從第三行開始,索引是2
EasyExcel.read(importFile, EmpSalary.class, empSalaryReadListener).sheet().headRowNumber(2).doRead();
List<EmpSalary> empSalaries = empSalaryReadListener.getEmpSalaries();
System.out.println(empSalaries.size());
}
@Data
public class EmpSalary {
private String realName;
private String empNo;
@ExcelProperty(value = "工資日期",converter = SalaryDateConverter.class)
private String salaryDate;
private Float baseAmount;
private Float fullAttendAmount;
private Float insurance;
}
表頭的讀取
有時候也會有這樣的需求,就是除了讀取表格的數據外,表頭的數據也要讀取出來,easyexcel的讀取監(jiān)聽器里的實現類里重寫invokeHead()方法即可,下面以讀取多行表頭,寫一個示例:
public class EmpSalaryReadListener implements ReadListener<EmpSalary> {
private List<EmpSalary> empSalaries=new ArrayList<>();
public List<EmpSalary> getEmpSalaries() {
return empSalaries;
}
@Override
public void invoke(EmpSalary data, AnalysisContext context) {
empSalaries.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
for (Integer key : headMap.keySet()) {
System.out.println("key:"+key+","+headMap.get(key).getStringValue());
}
System.out.println("---------");
}
}表頭信息也是逐行讀取的,即每讀取一行就會回調一下監(jiān)聽器的表頭讀取回調方法(invokeHead()),表頭信息結果是存儲在一個map中,map的key為excel表格列上的索引,value是表頭信息。對于多行合并單元格后,合并單元格后的內容在第一個格里,其他單元格也會占一個位置但是是空的;
以上就是使用Easyexcel實現不同場景的數據導出功能的詳細內容,更多關于Easyexcel數據導出的資料請關注腳本之家其它相關文章!
相關文章
分析java并發(fā)中的wait notify notifyAll
一個線程修改一個對象的值,而另一個線程則感知到了變化,然后進行相應的操作,這就是wait()、notify()和notifyAll()方法的本質。本文將詳細來介紹它們概念實現以及區(qū)別2021-06-06
tk-mybatis整合springBoot使用兩個數據源的方法
單純的使用mybaits進行多數據配置網上資料很多,但是關于tk-mybaits多數據源配置沒有相關材料,本文就詳細的介紹一下如何使用,感興趣的可以了解一下2021-12-12
Spring MessageSource獲取消息不符合預期的問題解決方案
最近我參與的產品要做國際化支持,選擇了用Spring MessageSource來實現,這個Spring 框架提供的工具使用很簡單,網上有各種教程文章,這里不做贅述,只說一個實際遇到的問題及解決方案,需要的朋友可以參考下2024-01-01
IDEA使用MyBatisCodeHelperPro來generator代碼的詳細教程
這篇文章主要介紹了IDEA使用MyBatisCodeHelperPro來generator代碼的詳細教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09

