본문 바로가기

Flutter-플러터/플러터 공부

Flutter sqlite3 파일 엑셀로 공유하기

반응형
문제 해결 목적

 

 

1. 현재 일기월장에서 사용 중인 sqlite3 의 파일을 엑셀 파일로 공유하는 기능 

2. sqlite3 의 날 것의 데이터가 아니라 사용자 편의성이 추가 된 엑셀 파일로 공유하기 

 

 

문제 해결 과정 

 

필요한 패키지는 요정도 입니다. 

 

- intl

- path_provider

- share_plus

- excel

 

1. 먼저 sqlite3의 db 파일을 불러옵니다. 해당 db 파일의 dbPath 를 변수를 만들어서 값을 불러옵니다. 
2. 해당 db 파일의 쿼리문을 사용해서 필요로 하는 테이블을 불러옵니다. 
3. 엑셀  파일을 만듭니다. 

4. 기존에 sqlite에 사용한 컬럼명을 매핑해서  사용자 편의성이 있는 글자로 바꿉니다. 
5. 조건문을 넣어서 해당 컬럼명이면 값의 모양이나 스타일을 추가해줍니다. 

6. share_plus 패키지의 기능을 추가해서 파일을 공유시켜줍니다. 

끝 

 

 

Future<void> exportDatabaseToExcelWithCustomHeaders() async {
    try {
      // 데이터베이스 열기
      String dbPath = await getDatabasesPath() + '/moneytracker.db';
      Database database = await openDatabase(dbPath);

      // 데이터베이스에서 데이터 읽기
      List<Map> results = await database.rawQuery('SELECT * FROM expenses');

      // Excel 파일 생성
      var excel = Excel.createExcel();
      Sheet sheetObject = excel['Sheet1'];

      // Excel에 사용할 컬럼 이름 매핑
      Map<String, String> columnMapping = {
        'createdTime': '날짜',
        'incomeType': '매출/지출',
        'name': '항목',
        'money': '금액',
        'content': '내용',
        'merchantName': '거래처'
      };

      // 스타일 정의
      CellStyle rightAlignStyle =
          CellStyle(horizontalAlign: HorizontalAlign.Right);

      // 헤더 삽입
      List<String> headers = columnMapping.values.toList();
      for (int i = 0; i < headers.length; i++) {
        sheetObject
            .cell(CellIndex.indexByColumnRow(columnIndex: i, rowIndex: 0))
            .value = TextCellValue(headers[i]);
      }

      // 데이터 삽입
      for (int i = 0; i < results.length; i++) {
        int j = 0;
        columnMapping.forEach((dbColumn, excelHeader) {
          String value;
          CellStyle? cellStyle = null;
          if (dbColumn == 'createdTime') {
            // 날짜를 원하는 형식으로 변환
            String rawDate = results[i][dbColumn]?.toString() ?? '';
            DateTime? parsedDate = DateTime.tryParse(rawDate);
            value = parsedDate != null
                ? DateFormat('yyyy-MM-dd').format(parsedDate)
                : '';
          } else if (dbColumn == 'money') {
            // 금액을 "50000원" 형식으로 변환하고 우측 정렬 스타일 지정
            double? amount =
                double.tryParse(results[i][dbColumn]?.toString() ?? '');
            if (amount != null) {
              value = NumberFormat('#,###').format(amount);
            } else {
              value = '';
            }
            cellStyle = rightAlignStyle;
          } else {
            value = results[i][dbColumn]?.toString() ?? '';
          }

          // 데이터 삽입 및 스타일 적용
          final cell = sheetObject.cell(
              CellIndex.indexByColumnRow(columnIndex: j, rowIndex: i + 1));
          cell.value = TextCellValue(value);

          if (cellStyle != null) {
            cell.cellStyle = cellStyle;
          }

          j++;
        });
      }

      // 파일 저장 경로 얻기
      final directory = await getApplicationDocumentsDirectory();
      String filePath = "${directory.path}/expenses.xlsx";

      // 파일 저장
      List<int>? fileBytes = excel.save();
      if (fileBytes != null) {
        File file = File(filePath)
          ..createSync(recursive: true)
          ..writeAsBytesSync(fileBytes);
        print('Excel File Created at $filePath');

        // 파일 공유
        final List<XFile> files = [XFile(file.path)];
        await Share.shareXFiles(files,
            text: 'Here is the exported Excel file with custom headers.');
      }

      // 데이터베이스 닫기
      await database.close();
    } catch (e) {
      print('An error occurred while exporting to Excel: $e');
    }
  }

 

 

 

완료 

728x90
반응형