为了账号安全,请及时绑定邮箱和手机立即绑定

调用高德API 实现自动计算两个地点之间驾车距离使用POI操作回写Excel

标签:
Java

前言

项目上有个一次需要查询两个地方之间的驾车距离,项目经理一开始让我们每个人查询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,希望自动化代码可以用到更多地方。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消