最近遇到一个需求,某网站导出数据无法导出想要的明细信息,因为多达一千多条数据所以手动抄写肯定不现实,于是看看有没有什么办法可以直接批量写进Excel表格中。
理了一下思路,决定先把所有业务单据的id获取存到本地,再遍历本地文件通过id请求接口把明细存到Excel表格中。
网站上返回的格式是text/html,查阅了相关资料决定直接导入Jsoup包
Jsoup的简介:
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,
可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
这个网址介绍的很详细
https://www.cnblogs.com/zhangyinhua/p/8037599.html
有了jsoup就很方便了,解析出文本内容后直接根据结构获取到想要的数据,并保存到本地
// 将所有订单id输入进txt文件
for (int page = 1; page <= 32; page++) {
// 创建一个新的 Connection, 和 get() 取得和解析一个HTML文件
Document doc = Jsoup.connect("url").get();
// 根据HTML的标签结构获取订单的id并写入TXT文件里
Elements links = doc.select("a");
File file = new File("D:" + File.separator + "id2.txt");
for (int i = 0; i < links.size(); i++) {
OutputStream out = null;
String href = links.get(i).toString();
int local = href.indexOf("id");
if (local != -1) {
// 有id 获取id
String id = href.substring(local + 3, href.lastIndexOf("\""));
id += ",";
try {
// 根据文件创建文件的输出流
out = new FileOutputStream(file, true);
String message = id;
// 把内容转换成字节数组
byte[] data = message.getBytes();
// 向文件写入内容
out.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭输出流
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
保存到本地之后肯定也需要读取,写一个方法用来读取
File readFile = new File("D:" + File.separator + "id2.txt");
InputStream in = null;
List<String> list = new ArrayList<>();
try {
in = new FileInputStream(readFile); //实例化字节流对象
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, "utf8"));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
String str = stringBuilder.toString();
list = Arrays.asList(str.split(","));
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return list;
能读取到之后就利用这些id请求获取数据明细的接口,然后写入Excel表格,需要用到一个工具类。
package com.cl.foryou.util;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.io.*;
import java.lang.reflect.Method;
public class ExcelUtil {
private HSSFWorkbook workbook = null;
/**
* 判断文件是否存在
*
* @param filePath 文件路径
* @return
*/
public boolean fileExist(String filePath) {
boolean flag = false;
File file = new File(filePath);
flag = file.exists();
return flag;
}
/**
* 41 * 判断文件的sheet是否存在
* 42 * @param filePath 文件路径
* 43 * @param sheetName 表格索引名
* 44 * @return
* 45
*/
public boolean sheetExist(String filePath, String sheetName) {
boolean flag = false;
File file = new File(filePath);
if (file.exists()) { //文件存在
//创建workbook
try {
workbook = new HSSFWorkbook(new FileInputStream(file));
//添加Worksheet(不添加sheet时生成的xls文件打开时会报错)
HSSFSheet sheet = workbook.getSheet(sheetName);
if (sheet != null)
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
} else { //文件不存在
flag = false;
}
return flag;
}
/**
* 66 * 创建新Sheet并写入第一行数据
* 67 * @param filePath excel的路径
* 68 * @param sheetName 要创建的表格索引
* 69 * @param titleRow excel的第一行即表格头
* 70 * @throws IOException
* 71 * @throws FileNotFoundException
* 72
*/
public void createSheet(String filePath, String sheetName, String titleRow[]) throws FileNotFoundException, IOException {
FileOutputStream out = null;
File excel = new File(filePath); // 读取文件
FileInputStream in = new FileInputStream(excel); // 转换为流
workbook = new HSSFWorkbook(in); // 加载excel的 工作目录
workbook.createSheet(sheetName); // 添加一个新的sheet
//添加表头
Row row = workbook.getSheet(sheetName).createRow(0); //创建第一行
try {
for (int i = 0; i < titleRow.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(titleRow[i]);
}
out = new FileOutputStream(filePath);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 100 * 创建新excel.
* 101 * @param filePath excel的路径
* 102 * @param sheetName 要创建的表格索引
* 103 * @param titleRow excel的第一行即表格头
* 104
*/
public void createExcel(String filePath, String sheetName, String titleRow[]) {
//创建workbook
workbook = new HSSFWorkbook();
//添加Worksheet(不添加sheet时生成的xls文件打开时会报错)
workbook.createSheet(sheetName);
//新建文件
FileOutputStream out = null;
try {
//添加表头
Row row = workbook.getSheet(sheetName).createRow(0); //创建第一行
for (int i = 0; i < titleRow.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(titleRow[i]);
}
out = new FileOutputStream(filePath);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件.
*
* @param filePath 文件路径
*/
public boolean deleteExcel(String filePath) {
boolean flag = false;
File file = new File(filePath);
// 判断目录或文件是否存在
if (!file.exists()) {
return flag;
} else {
// 判断是否为文件
if (file.isFile()) { // 为文件时调用删除文件方法
file.delete();
flag = true;
}
}
return flag;
}
/**
* 往excel中写入.
*
* @param filePath 文件路径
* @param sheetName 表格索引
* @param object
*/
public void writeToExcel(String filePath, String sheetName, Object object, String titleRow[]) {
//创建workbook
File file = new File(filePath);
try {
workbook = new HSSFWorkbook(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
HSSFSheet sheet = workbook.getSheet(sheetName);
// 获取表格的总行数
int rowCount = sheet.getLastRowNum() + 1; // 需要加一
try {
Row row = sheet.createRow(rowCount); //最新要添加的一行
//通过反射获得object的字段,对应表头插入
// 获取该对象的class对象
Class<? extends Object> class_ = object.getClass();
for (int i = 0; i < titleRow.length; i++) {
String title = titleRow[i];
String UTitle = Character.toUpperCase(title.charAt(0)) + title.substring(1, title.length()); // 使其首字母大写;
String methodName = "get" + UTitle;
Method method = class_.getDeclaredMethod(methodName); // 设置要执行的方法、
String data = method.invoke(object).toString(); // 执行该get方法,即要插入的数据
Cell cell = row.createCell(i);
cell.setCellValue(data);
}
out = new FileOutputStream(filePath);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在主方法里写一个循环,依次传入需要请求的接口地址。title[]和titleDate[]是对应的,作为Excel表格每一行的标题。中间省略了一段对实体类的操作,实体类封装好需要的字段,操作HTML把数据给实体类的字段,之后交给工具类的方法处理就行了
Document doc = Jsoup.connect(url).get();
// 需要的数据在HTML中的“table”标签里,结构分为两部分,先全部提取出来
Elements links = doc.select("table");
// 存放第一部分
Element part1 = links.get(0);
// 存放第二部分
Element part2 = links.get(1);
// System.out.println(part1 + "第一部分");
// System.out.println(part2 + "第二部分");
String filePath = "D:/蔬菜数据汇总.xls";
String sheetName = "测试";
//Excel文件易车sheet页的第一行
String title[] = {"入库单号", "订单号", "合同号", "收货地", "结算方式", "付款方式", "审核人", "审核日期", "状态", "备注", "编号", "商品编码", "商品名称", "商品条码", "商品规格", "应收数量", "入库数量", "成本价(含税)", "进项税率", "含税金额", "税额", "入库数量合计", "含税金额合计"};
//Excel文件易车每一列对应的数据
String titleDate[] = {"receiptNumber", "orderNumber", "contractNumber", "receivingPlace", "clearingForm", "paymentTypes", "reviewer", "auditDate",
"condition", "mark", "no", "commodityCode", "commodityName", "barCode", "specifications", "receivable", "warehousing", "costPrice", "inputTaxRate", "taxAmount", "amountOfTax", "warehousingSum", "taxAmountSum"};
ExcelUtil em = new ExcelUtil();
//判断该名称的文件是否存在
boolean fileFlag = em.fileExist(filePath);
if (!fileFlag) {
em.createExcel(filePath, sheetName, title);
}
//判断该名称的Sheet是否存在
boolean sheetFlag = em.sheetExist(filePath, sheetName);
//如果该名称的Sheet不存在,则新建一个新的Sheet
if (!sheetFlag) {
try {
em.createSheet(filePath, sheetName, title);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// orderForExcel.setNo(part2.select("td").get(0).text());
// orderForExcel.setNo(part2.select("td").get(0).text());
//写入到excel
em.writeToExcel(filePath, sheetName, entity, titleDate);
展示一下效果