前言
项目上有个一次需要查询两个地方之间的驾车距离,项目经理一开始让我们每个人查询100个地点,手动查询然后手动写Excel,只有一百个,手动查询高德地图,估计就半个小时,所以我没想过使用代码来解决这个问题,因为调试参数需要时间,所以我不想加班,手动查询了一次,可是第二天,项目经理又分配了同样的任务,这次是1000个,这要是手动查询得花两三个小时,这时,我才开始写代码
步骤其实也很简单,先注册高德开发者平台
https://lbs.amap.com/api/javascript-api/guide/geometry/geometry
然后就可以根据实例开始写代码了
package com.caeser.midrug.util;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
/**
* @author caeser
* @date 2021-10-22 14:05:57
* @desc 读取Excel数据
*/
public class ExcelData {
public XSSFSheet sheet;
public XSSFWorkbook sheets;
public FileInputStream fileInputStream;
public File excelFile ;
/**
* 构造函数,初始化excel数据
* @param filePath excel路径
* @param sheetName sheet表名
*/
ExcelData(String filePath,String sheetName){
fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
excelFile=new File(filePath);
sheets = new XSSFWorkbook(fileInputStream);
//获取sheet
sheet = sheets.getSheet(sheetName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据行和列的索引获取单元格的数据
* @param row
* @param column
* @return
*/
public String getExcelDateByIndex(int row,int column){
XSSFRow row1 = sheet.getRow(row);
String cell = row1.getCell(column).toString();
return cell;
}
public XSSFSheet getSheet(){
return sheet;
}
public XSSFWorkbook getSheets(){
return sheets;
}
public File getExcelFile(){
return excelFile;
}
public static void setExcelDateByIndex(int row, int column, String paramValue, ExcelData target){
XSSFRow row1 = target.getSheet().getRow(row);
//创建单元格,括号中的数字表示该行的第几列,从0开始
Cell cella = row1.createCell(column);
//向单元格中写数据,可写入各种类型的数据(如Boolean,int,double,String等)
cella.setCellValue(paramValue);
return ;
}
/**
* 根据某一列值为“******”的这一行,来获取该行第x列的值
* @param caseName
* @param currentColumn 当前单元格列的索引
* @param targetColumn 目标单元格列的索引
* @return
*/
public String getCellByCaseName(String caseName,int currentColumn,int targetColumn){
String operateSteps="";
//获取行数
int rows = sheet.getPhysicalNumberOfRows();
for(int i=0;i<rows;i++){
XSSFRow row = sheet.getRow(i);
String cell = row.getCell(currentColumn).toString();
if(cell.equals(caseName)){
operateSteps = row.getCell(targetColumn).toString();
break;
}
}
return operateSteps;
}
//打印excel数据
public void readExcelData(){
//获取行数
int rows = sheet.getPhysicalNumberOfRows();
for(int i=0;i<rows;i++){
//获取列数
XSSFRow row = sheet.getRow(i);
int columns = row.getPhysicalNumberOfCells();
for(int j=0;j<columns;j++){
String cell = row.getCell(j).toString();
System.out.println(cell);
}
}
}
// HTTP GET请求
static Map<String,Object> sendGet(String paUrl, String param) throws Exception {
Map<String,Object> resultMap=new HashMap<>();
String USER_AGENT = "Mozilla/5.0";
String url = paUrl+"?"+param;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//默认值我GET
con.setRequestMethod("GET");
//添加请求头
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
resultMap.put("responseCode",responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//打印结果
System.out.println(response.toString());
resultMap.put("responseInfo",response.toString());
return resultMap;
}
//测试方法
public static void main(String[] args) throws Exception {
ExcelData sheet1 = new ExcelData("D:\\反馈医院间距离_all.xlsx", "Sheet1");
String getLocationAPI_URL="https://restapi.amap.com/v3/geocode/geo";
String getDrivingAPI_URL="https://restapi.amap.com/v3/direction/driving";
String amapKey="sfsufosufosuofusodufosudf";
String addressName="北京西鹤年堂中医医院";
String cityName="北京";
String concatParam="key="+amapKey+"&address="+addressName+"&city="+cityName;
Map<String,Object> reusltMsg= sendGet(getLocationAPI_URL,concatParam);
String codeStr=reusltMsg.get("responseCode").toString();
JsonNode locationObj=null;
if("200".equals(codeStr)){
// 如果是200
String rspInfo=reusltMsg.get("responseInfo").toString();
JsonNode jsonNode= JsonUtil.string2Json(rspInfo);
JsonNode queryObj=jsonNode.get("geocodes");
locationObj=queryObj.get(0).get("location");
String queryStr = locationObj.toString().replaceAll("\"","");
System.out.println(queryStr);
}
String aLocation="";
String bLocation="";
for(int a=1799;a<1890;a++){
String cellN = sheet1.getExcelDateByIndex(a, 0);
// 根据第一个名称获取经纬坐标
concatParam="key="+amapKey+"&address="+cellN+"&city="+cityName;
reusltMsg= sendGet(getLocationAPI_URL,concatParam);
codeStr=reusltMsg.get("responseCode").toString();
if("200".equals(codeStr)){
// 如果是200
String rspInfo=reusltMsg.get("responseInfo").toString();
JsonNode jsonNode= JsonUtil.string2Json(rspInfo);
JsonNode queryObj=jsonNode.get("geocodes");
if(queryObj.get(0)==null){
//
}else{
locationObj=queryObj.get(0).get("location");
String queryStr = locationObj.toString().replaceAll("\"","");
aLocation=queryStr;
System.out.println(queryStr);
}
}
String cellM = sheet1.getExcelDateByIndex(a, 1);
// 根据第二个名字获取经纬坐标
concatParam="key="+amapKey+"&address="+cellM+"&city="+cityName;
reusltMsg= sendGet(getLocationAPI_URL,concatParam);
codeStr=reusltMsg.get("responseCode").toString();
if("200".equals(codeStr)){
// 如果是200
String rspInfo=reusltMsg.get("responseInfo").toString();
JsonNode jsonNode= JsonUtil.string2Json(rspInfo);
JsonNode queryObj=jsonNode.get("geocodes");
if(queryObj.get(0)==null){
//
}else{
locationObj=queryObj.get(0).get("location");
String queryStr = locationObj.toString().replaceAll("\"","");
bLocation=queryStr;
System.out.println(queryStr);
}
}
System.out.println(cellN+","+cellM+"\n");
System.out.println(aLocation+","+bLocation+"\n");
// 根据两个经纬坐标查询 驾车距离 a\b location有一个为空都不去查询
if("".equals(aLocation)||"".equals(bLocation)){
// 存在有一个为空
}else{
concatParam="key="+amapKey+"&origin="+aLocation+"&destination="+bLocation;
reusltMsg= sendGet(getDrivingAPI_URL,concatParam);
codeStr=reusltMsg.get("responseCode").toString();
if("200".equals(codeStr)){
// 如果是200
String rspInfo=reusltMsg.get("responseInfo").toString();
JsonNode jsonNode= JsonUtil.string2Json(rspInfo);
JsonNode queryObj=jsonNode.get("route");
JsonNode pathsObj=queryObj.get("paths");
if(pathsObj.get(0)==null){
//
}else{
// 获取驾车距离 单位 米,转换为公里
String distanceStr=pathsObj.get(0).get("distance").toString().replaceAll("\"","");
double value = Double.valueOf(distanceStr)/1000;
// #.00 表示两位小数
DecimalFormat df = new DecimalFormat("#0.0"); // 保留1位小数,四舍五入
String valueDF=df.format(value);
// 写入Excel
setExcelDateByIndex(a,3,valueDF,sheet1);
System.out.println("方法二:" + valueDF);
System.out.println("getDIs");
}
}
}
aLocation="";
bLocation="";
}
//把Excel工作薄写入到Excel文件
FileOutputStream os = new FileOutputStream(sheet1.getExcelFile());
sheet1.getSheets().write(os);
os.flush();
os.close();
System.out.println("success!");
//获取第二行第4列
// String cell2 = sheet1.getExcelDateByIndex(1, 3);
//根据第3列值为“customer23”的这一行,来获取该行第2列的值
// String cell3 = sheet1.getCellByCaseName("customer23", 2,1);
// System.out.println(cell2);
// System.out.println(cell3);
}
}结尾
其实如果数据量很小,花时间写代码实现自动化纯属娱乐学习了,我一开始就是想偷个懒,觉得手动查询也挺快的,后来发现我太天真了,自动化代码并不难,就看你想不想用了。
上面就是我全部的代码,包括了POI和调用高德API,其实就是发送请求,然后处理请求结果,最后操作字符串回写Excel,希望自动化代码可以用到更多地方。