使用语言:JAVA
需求:读取一个Excel表格里面的数据(例如:姓名+分数),对其进行重新排序(按分数高低),然后输出在另一个Excel表格。
一般对需求我们都采取拆分思维。
将大问题拆成小问题,小问题解决了,整个大问题也就解决了。
这个需求很明确,需要解决三个问题:
我们这里要求使用 Java 语言,而 Java 语言一个很重要的点就是面向对象。
因此首先我们要考虑一下,这个题目里面有哪些类需要我们创建。
大概可以想象需要下面这些类:
读取数据类:ExcelReader
写入数据类:ExcelWriter
数据排序类:由于 Java API 自带,所以不需要重复造轮子
数据模型类:StudentScore
启动类:ParserStart,带有 main 方法
大概的 UML 图如下:
此时我们可以写出 v0.1 代码:
ExcelReader.java:
import java.util.List; public class ExcelReader { public List<StudentScore> read(String fileName) { //TODO return null; } } 复制代码
ExcelWriter.java:
import java.util.List; public class ExcelWriter { public void write(String fileName, List<StudentScore> list) { //TODO } } 复制代码
StudentScore.java:
public class StudentScore { private String name; private int score; public StudentScore(String name, int score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } } 复制代码
ParserStart.java:
import java.util.List; public class ParserStart { public static void main(String[] args) { // 第一步:读取数据 List<StudentScore> dataList = new ExcelReader().read("input.xls"); // 第二步:排序 //TODO // 第三部:写入数据 new ExcelWriter().write("output.xls", dataList); } } 复制代码
好了,基本框架搭好了。接下来就一步一步来实现我们的方法。
Excel 的读取方法有第三方的库可以使用,因此我们不需要自己写。
我们这里使用的是第三方的 Apache 提供的 POI 库。
下载链接地址: poi.apache.org/download.ht…
写这篇文章时使用到的版本是 4.1.0
解压然后将 jar 包引入 Eclipse 项目即可。
接下来就是实际编写代码了,详情见注释。
我们要读取的文件示例如下:
ExcelReader.java:
import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; public class ExcelReader { public List<StudentScore> read(String fileName) throws EncryptedDocumentException, IOException { if (fileName == null) return null; File xlsFile = new File(fileName); if (!xlsFile.exists()) return null; // 工作表 Workbook workbook = WorkbookFactory.create(xlsFile); // 表个数 int numberOfSheets = workbook.getNumberOfSheets(); // System.out.println(numberOfSheets); if (numberOfSheets <= 0) return null; List<StudentScore> list = new ArrayList<>(); //我们的需求只需要处理一个表,因此不需要遍历 Sheet sheet = workbook.getSheetAt(0); // 行数 int rowNumbers = sheet.getLastRowNum() + 1; // System.out.println(rowNumbers); StudentScore score; // 读数据,第二行开始读取 for (int row = 1; row < rowNumbers; row++) { Row r = sheet.getRow(row); // System.out.println(r.getPhysicalNumberOfCells()); //我们只需要前两列 if (r.getPhysicalNumberOfCells() >= 2) { score = new StudentScore(r.getCell(0).toString(), (int) Double.parseDouble(r.getCell(1).toString())); list.add(score); } } return list; } } 复制代码
在 v0.2 版本中,我们成功读取了数据,但是我们读取的数据是按照 Excel 里面的顺序的,因此我们需要做排序处理。Java 函数库有对集合进行排序的方法。不过我们需要对 Model 进行额外处理,添加排序规则。因为排序可以是从小到大排,也可以是从大到小排。
StudentScore.java:
public class StudentScore implements Comparable<StudentScore>{ private String name; private int score; public StudentScore(String name, int score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } @Override public String toString() { return "StudentScore [name=" + name + ", score=" + score + "]"; } @Override public int compareTo(StudentScore o) { return o.score - this.score; } } 复制代码
ParserStart.java:
import java.util.Collections; import java.util.List; public class ParserStart { public static void main(String[] args) throws Exception{ // 第一步:读取数据 List<StudentScore> dataList = new ExcelReader().read("resource/input.xls"); System.out.println(dataList); // 第二步:排序 Collections.sort(dataList); System.out.println(dataList); // 第三部:写入数据 // new ExcelWriter().write("output.xls", dataList); } } 复制代码
在 v0.3 版本中,我们完成了数据的排序,接下来我们需要将排好序的数据写到 output.xls 中。
ExcelWriter.java
import java.io.File; import java.io.IOException; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class ExcelWriter { public void write(String fileName, List<StudentScore> list) throws IOException { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("StudentScore"); // 创建Excel标题行,第一行 HSSFRow headRow = sheet.createRow(0); headRow.createCell(0).setCellValue("姓名"); headRow.createCell(1).setCellValue("分数"); // 往Excel表中遍历写入数据 for (StudentScore studentScore : list) { createCell(studentScore, sheet); } File xlsFile = new File(fileName); System.out.println("xlsFile exist="+xlsFile.exists()); System.out.println("xlsFile exist="+xlsFile.getAbsolutePath()); workbook.write(xlsFile);// 或者以流的形式写入文件 workbook.write(new FileOutputStream(xlsFile)); workbook.close(); } // 创建Excel的一行数据。 private void createCell(StudentScore studentScore, HSSFSheet sheet) { HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1); dataRow.createCell(0).setCellValue(studentScore.getName()); dataRow.createCell(1).setCellValue(studentScore.getScore()); } } 复制代码
ParserStart.java
import java.util.Collections; import java.util.List; public class ParserStart { public static void main(String[] args) throws Exception { // 第一步:读取数据 List<StudentScore> dataList = new ExcelReader().read("resource/input.xls"); System.out.println(dataList); // 第二步:排序 Collections.sort(dataList); System.out.println(dataList); // 第三部:写入数据 new ExcelWriter().write("resource/output.xls", dataList); } } 复制代码
到此,通过几个版本的迭代,我们的需求就实现了。
NOTE:
在本项目中,input.xls 放在 resource 文件夹下面。所以最终版本传入的路径是 resource/input.xls。另外输出的时候这边发现 Eclipse 没有显示出来 output.xls,需要刷新一下。
此外,下载我的项目运行验证时,可能需要修改下 JRE。
另外 jar 包不要引入错位置了:
当然,还有几个待完善的点需要说明下:
另外说一下有什么应用场景吧,其实还真有。
移动端有多语言,想象一下产品给你一张带有多语言的 excel 表。
如果你一个一个拷贝到多个语言的资源文件下,这效率难以想象。
而如果你用了这一节的内容,分分钟读取 excel 按照你要的规则组装后输出到控制台。
想想就有点 6 啊。
好了,本期内容到此结束,欢迎留言交流讨论。
源码获取地址:
github.com/nesger/Java…参考链接:
Java读取Excel数据:基于Apache POI(一)
Java读取和解析Excel数据:基于Apache POI(二)
Java导出数据行写入到Excel表格:基于Apache POI