最近遇到一個需求,某網站導出數據無法導出想要的明細信息,因為多達一千多條數據所以手動抄寫肯定不現實,於是看看有沒有什么辦法可以直接批量寫進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);
展示一下效果