下载文件,图片/解析excel

5.1 下载文件,图片

 学习了如何请求图片,excel等文件,此类二进制文件无法把内容输出在console进行查看,所以请求结果必须写入文件。

  在Java中写文件必须经历三个步骤:

创建文件对象
   ↓
写入内容
   ↓
关闭写入操作

打开和关闭的步骤,是为了确保同一个文件同时只能被同一个程序写,否则内容会错乱。

写入文本文件
在程序中写入字符串内容的语句
import java.io.File;
import java.io.FileWriter;

// 文件对象
File file = new File("foo.txt");

// 写入内容
FileWriter fileWritter = new FileWriter(file.getName());
fileWritter.write(content);

// 关闭
fileWritter.close();

File是文件类,FileWriter是用来给文件写入内容的类。

写入二进制文件

  当然,写入的内容不只是文本,excel等二进制文件也可以。

   请求一个excel文件(网址https://style.youkeda.com/img/ham/course/py2/china-city-list.xlsx),文件数据类型是byte[].

   假设文件数据的变量是byte[] data,那么写入本地文件的代码如下:

import java.io.File;
import java.io.FileOutputStream;

// 文件对象
File file = new File("china-city-list.xlsx");

// 写文件
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);

// 必须刷新并关闭
fos.flush();
fos.close();

与写入文本内容不同,写入二进制内容,需要用FileOutputStream,再次强调,必须执行刷新,关闭操作。

 

注意:下载图片和下载其他文件别无二致,而且图片都是二进制文件。


 5.2 解析excel

  另一种常见的文件是excel文件

依赖库:easyexcel是操作Excel文件的库,使用前必须在pom.xml文件中加入对库的依赖。

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>2.1.6</version>
</dependency>

调用库:

  excel文件是多sheet模式的,每个sheet实际上是一个表格,表格又分为行和列,所以解析数据的路径一定是:sheet->行->列。第一个sheet、第一行、第一列的位置是0,0,0

  下载了xzq_201907.xlsx文件后,解析其内容

import com.alibaba.excel.EasyExcel;
import java.util.Map;
import java.util.List;

// 读取第一个sheet
List<Map<Integer, String>> sheetDatas = EasyExcel.read("xzq_201907.xlsx").sheet(0).doReadSync();
// List 中每个元素表示一行
for (Map<Integer, String> rowData : sheetDatas) {
  // Map 中用序号指代每一列
  for (Integer index : rowData.keySet()) {
    // 列值
    String columnValue = rowData.get(index);
  }
}

下载文件,图片/解析excel

 

 

解析文件的第一个步骤是读取文件内容,调用EasyExcel.read()方法,传入文件名称,然后这里解析的第一个工作表,调用sheet()方法,传入参数0.最后的doRead()表示同步方式读取文件内容,返回一个读取到的内容集合List,这是一个连贯的写法。返回的List集合中,系统用Map类表示一行数据

 

自动转换为类

  如果不能确定每一行含义,用Map表示每一列的数据,如果知道excel文件的每一列的含义,用自定义类表示会更加直观

  

import com.alibaba.excel.EasyExcel;
import java.util.List;

// 读取第一个sheet
List<DemoData> sheetDatas = EasyExcel.read("xzq_201907.xlsx").head(DemoData.class).sheet(0).doReadSync();

DemoData就是自定义的类,表示一行数据,类的每个属性都表示一列的值。

 Map更灵活,自定义类更直观更易理解,一般行数不太多,不会变化用自定义类。

返回值为List<DemoData>就表示把每一行都转换为一个DemoData的实例对象,放入List集合中。

// 属性定义的顺序必须与列顺序保持一致
public class DemoData {
  private String code1;
  private String city1;
  private String code2;
  private String city2;
  private String code3;
  private String city3;
}

下载文件,图片/解析excel

 

 

code1是第一个属性,映射excel文件第一列的值,注意excel表的列与自定义的属性,是按顺序一一对应的,不是按名称。

 

 例:任务:

下载excel文件:

https://style.youkeda.com/img/ham/course/py2/china-city-list.xlsx

完成
com.youkeda.test.http.ExcelAsker
类,遍历其内容,当然,本文件只有一个sheet,所以只需要读取第一个sheet内容即可。
遍历结果要求::excel表格的一行内容输出到console一行中,每个单元格之间用空格隔开即可。

首先在pom.xml中添加easyexcel依赖库,然后完善com.youkeda.test.http.ExcelAsker库:
 1 package com.youkeda.test.http;
 2 
 3 
 4 import com.alibaba.excel.EasyExcel;
 5 import com.alibaba.fastjson.JSON;
 6 import java.io.File;
 7 import java.io.FileOutputStream;
 8 import java.io.IOException;
 9 import java.util.List;
10 import java.util.Map;
11 import okhttp3.OkHttpClient;
12 import okhttp3.Request;
13 import okhttp3.Response;
14 
15 public class ExcelAsker {
16 
17   /**
18    * 根据输入的url,读取页面内容并返回
19    */
20   public byte[] getFile(String url) {
21     // okHttpClient 实例
22     OkHttpClient okHttpClient = new OkHttpClient();
23     // 定义一个request
24     Request request = new Request.Builder().url(url).build();
25     byte[] bytes = null;
26     try {
27       // 执行请求
28       Response response = okHttpClient.newCall(request).execute();
29       bytes = response.body().bytes();
30     } catch (IOException e) {
31       // 抓取异常
32       System.out.println("request " + url + " error . ");
33       e.printStackTrace();
34     }
35 
36     return bytes;
37   }
38 
39   public static void main(String[] args) {
40     String url = "https://style.youkeda.com/img/ham/course/py2/china-city-list.xlsx";
41     ExcelAsker asker = new ExcelAsker();
42     byte[] data = asker.getFile(url);
43 
44     try {
45       File file = new File("china-city-list.xlsx");
46 
47       FileOutputStream fos = new FileOutputStream(file);
48       fos.write(data);
49 
50       fos.flush();
51       fos.close();
52 
53       System.out.println("下载成功");
54     } catch (IOException e) {
55       e.printStackTrace();
56     }
57 
58     // 解析 excel 文件
59     List<Map<Integer, String>> sheetDatas = EasyExcel.read("china-city-list.xlsx").sheet(0).doReadSync();
60     for (Map<Integer, String> rowData : sheetDatas) {
61       for (Integer index : rowData.keySet()) {
62         System.out.print(rowData.get(index) + " ");
63       }
64       System.out.println("");
65     }
66   }
67 }

下载文件,图片/解析excel

 

 



 

下载文件,图片/解析excel

上一篇:mongoTemplate.group分组查询


下一篇:粘包问题