Never give up

Flutter - Kakao local Rest API, Create excel file 본문

해왔던 삽질..

Flutter - Kakao local Rest API, Create excel file

대기만성 개발자 2021. 7. 3. 17:38
반응형

이번에는 카카오 road rest api를 이용해서 주소 관련된 정보를 가져오는것과

 

가져온 정보를 excel파일로 만들어보는 예제를 만들어봤습니다

 

먼저 사용한 패키지는 

excel (null safety적용버전) : 엑셀파일 생성 및 수정

(링크 : https://pub.dev/packages/excel)

 

http : kakao local rest api 콜

(링크 : https://pub.dev/packages/http)

 

path, path provider : 파일 위치 및 저장

(링크 : https://pub.dev/packages/path)

(링크 : https://pub.dev/packages/path_provider)

 

permission handler : 파일 저장용 권한 처리

(링크 : https://pub.dev/packages/permission_handler)

 

extension, restAPIKey

// 스낵바 사용하기 편하게 만들어놓은 extension
extension SnackBarWithKey on GlobalKey<ScaffoldMessengerState> {
  ScaffoldFeatureController<SnackBar, SnackBarClosedReason> show(String text) {
    return this.currentState!.showSnackBar(SnackBar(content: Text(text)));
  }
}

//rest api key
const String restAPIKey = '발급받은 키를 입력해주세요';

address model

class AddressModel {
  String? name, address, lat, lng;

  AddressModel({this.name, this.address, this.lat, this.lng});

  factory AddressModel.fromJson(Map<String, dynamic> json) {
    return AddressModel(
        name: json['place_name'],
        address: json['address_name'],
        lat: json['y'],
        lng: json['x']);
  }

  //excel raw에 삽입하기 위한 list
  List<String> toList() => [name!, address!, lng!, lat!];

  Map<String, dynamic> toJson() =>
      {'place_name': name, 'address_name': address, 'y': lat, 'x': lng};
}

main

late Excel _excel;
  late Sheet _sheetObject;
  final GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey =
      GlobalKey<ScaffoldMessengerState>();

  List<String> _list = ['네이버', '카카오', '쿠팡', '배달의민족'];

  @override
  Widget build(BuildContext context) {
    return ScaffoldMessenger(
      key: _scaffoldMessengerKey,
      child: Scaffold(
        appBar: AppBar(title: Text(widget.title)),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
              ElevatedButton(
                  onPressed: () {
                    _excel = Excel.createExcel();

                    _sheetObject = _excel['SheetName'];

                    _scaffoldMessengerKey.show('Excel created');
                  },
                  child: Text('Create')),
              ElevatedButton(
                  onPressed: () async {
                    AddressModel model;

                    http.Response? response;

                    bool isFailed = false;

                    for (int i = 0; i < _list.length; i++) {
                      try {
                        response = await http.get(
                            Uri.parse(
                                'https://dapi.kakao.com/v2/local/search/keyword.json?page=1&size=1&sort=accuracy&query=${_list[i]}'),
                            headers: {'Authorization': 'KakaoAK $restAPIKey'});
                      } catch (e) {
                        print('error : $e');
                        _scaffoldMessengerKey.show('Error : $e');
                        isFailed = true;
                      }

                      model = AddressModel.fromJson(
                          jsonDecode(response!.body)['documents'][0]);

                      debugPrint('model : ${model.toJson()}');

                      _sheetObject.insertRowIterables(model.toList(), i + 1);
                    }

                    if (isFailed) {
                      _scaffoldMessengerKey.show('Failed!');
                    } else {
                      _sheetObject
                          .insertRowIterables(['이름', '주소', '위도', '경도'], 0);
                      _scaffoldMessengerKey.show('Success!');
                    }
                  },
                  child: Text('Write excel')),
              ElevatedButton(
                  onPressed: () async {
                    PermissionStatus status = await Permission.storage.status;

                    if (status != PermissionStatus.granted) {
                      await Permission.storage.request();
                    }

                    if (status == PermissionStatus.granted) {
                      List<int>? fileBytes = _excel.save();
                      Directory directory =
                          await getApplicationDocumentsDirectory();
                      debugPrint('directory : $directory');

                      File(join('${directory.path}/excel.xlsx'))
                        ..createSync(recursive: true)
                        ..writeAsBytesSync(fileBytes!);

                      _scaffoldMessengerKey.show('Saved!');
                    } else {
                      _scaffoldMessengerKey.show('Storage access is denied');
                    }
                  },
                  child: Text('Save excel file')),
            ])
          ],
        ),
      ),
    );
  }

 

결과

< 완벼크!? >

 

간단하게 버튼을 3개 만들어서 3단계로 적용을 해봤습니다

 

1. 엑셀 만들기

2. api call로 정보를 가져와서 엑셀에 뿌려주기

3. 저장소에 저장하기

 

엑셀 관련부분은 많은 기능을 사용하지도 않았고, example 부분에

 

필요한 소스코드가 잘 나와있어서 굳이 설명드릴 필요는 없을거 같고

 

api call 부분은 kakao local api 부분에서 콜 하는 방식을 이해하시면 크게 어려운 부분은 없을거라 생각되는데

(링크 : https://developers.kakao.com/docs/latest/ko/local/dev-guide#search-by-keyword)

 

먼저 간단하게 테스트 해보면 더 쉬울거 같아서 접근 방법을 말씀드리자면

 

카카오 api test페이지가 있어서 적용해보면 다음과 같이 나옵니다

curl -X GET "https://dapi.kakao.com/v2/local/search/keyword.json?page=1&size=1&sort=accuracy&query=%EC%B9%B4%EC%B9%B4%EC%98%A4" \
	-H "Authorization: KakaoAK {REST_API_KEY}"

 

-h 부분은 header로 빼먹으면 인증관련 문제로 데이터를 가져올 수 없고

 

get부분에 보면 url을 따라가다보면 의미를 알 수 있습니다

 

"https://dapi.kakao.com/v2/local/search/keyword.json?page=1&size=1&sort=accuracy&query=%EC%B9%B4%EC%B9%B4%EC%98%A4"

 

api의 local에서 keyword를 검색을 하는데, json 형태로 받을 것이고, page는 1개 사이즈는 1개 정렬은 정확도 순으로, 그리고 query부분에 필요한 키워드를 입력 정도로 요약할 수 있을 거 같습니다

 

저장소 관련부분도 엑셀 예제부분에 잘 나와있는데 한가지 주의해야될점이 

 

엑셀 example에 보면 join에 directory를 그냥 넣어주는데, path를 넣어줘야됩니다

//잘못된 방식(에러 발생!)
File(join('$directory/excel.xlsx'))

//이게 맞습니다!
File(join('${directory.path}/excel.xlsx'))

혹시 저장한 장소가 헷갈리는 분들을 위해 경로를 사진으로 보여드리자면

(본인이 만든 패키지 경로의 app_flutter 폴더 안)

< 파일 위치 >

 

 

 

-- 이하 필자의 헛소리 타임이 시작될 예정이니 예제만 확인하실 분들은 스킵하시면 됩니다

 

 

사실 VBA로 해도 되는데 왜 굳이 flutter로 했나 하는 궁금증이 있으실거 같아 말씀드리자면..

 

Visual basic을 배우기도 했고 script macro에 대한 개념도 어느정도 있긴한데..

 

안한지 오래돼서 까먹기도 했고.. pub dev에 검색했더니 excel 패키지가 있어서

 

한번 시험삼아 해봤는데 너무 잘되더군요..(쓸대없는 실험정신)

< Flutter 쩐다!! >

추가로 요즘 체력적인 문제로 포스트가 뜸한데.. 그만큼 삽질도 덜 하고 있는거 같아서 조금 걱정이 됩니다.

 

삽질을 많이할수록 실력이 느는것을 알기에 열심히 포스트 해야될거 같습니다..

반응형
Comments