Java/Kotlin 으로 Google Sheet 에 접속하는 예제는 사실 구글에 아주 잘 나와있다. https://developers.google.com/sheets/api/quickstart/java?hl=ko 를 보면 샘플이 있는데, 이걸 돌려보면 되는 사람도 있고 잘 되지 않는 경우도 있을 텐데… 그 이유에 대해서 살짝 적어볼려고 한다.
구글 인증 방식은 두 가지(OAuth 클라이언트ID, ServiceAccount)
위의 링크를 잘 읽어보면 인증 정보 만들기에서 OAuth 클라이언트 ID로 만들어진 경우이다. 그런데, python 등에서 사용하다보면 보통 ServiceAccount 를 이용하는 형태를 스게 되는데, 이 두가지가 서로 달라서 위의 샘플로 ServiceAccount 형태의 인증을 요청하면 InvalidArgumentException을 만나게 된다.
위의 링크에서 전자(OAuth 클라이언트ID)의 방식을 잘 설명하고 있으므로 여기서는 후자만 다룬다.
접속 방법
간단한 접속 코드는 다음과 같다. (GoogleCredential 이 그런데 deprecated 되는 건 함정)
import com.google.api.client.auth.oauth2.Credential
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.gson.GsonFactory
import com.google.api.services.sheets.v4.Sheets
import com.google.api.services.sheets.v4.SheetsScopes
import org.springframework.context.annotation.Configuration
import java.io.IOException
import java.security.GeneralSecurityException
import java.util.*
@Configuration
class GoogleAuthorizationConfig {
private val applicationName: String = "test-api"
private val credentialsFilePath: String = "/credentials.json"
private val tokensDirectoryPath: String = "tokens"
@Throws(IOException::class, GeneralSecurityException::class)
private fun authorize(): Credential {
val inputStream = GoogleAuthorizationConfig::class.java.getResourceAsStream(credentialsFilePath)
val googleCredential = GoogleCredential.fromStream(inputStream)
.createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS_READONLY))
return googleCredential
}
@get:Throws(IOException::class, GeneralSecurityException::class)
val sheetsService: Sheets
get() {
val credential: Credential = authorize()
return Sheets.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JSON_FACTORY, credential
)
.setApplicationName(applicationName)
.build()
}
companion object {
private val JSON_FACTORY: com.google.api.client.json.JsonFactory = GsonFactory.getDefaultInstance();
}
}
그리고 이제 각 sheet 정보와 각각의 데이터를 가져오는 걸 알아보자.
fun getSpreadSheets(page: String) {
val sheetsService = googleAuthorizationConfig.sheetsService
val sheets = sheetsService.spreadsheets().get(page).execute()
sheets.sheets.map {
println(it.properties.title)
val sheet = sheetsService.spreadsheets().values().get(page, it.properties.title).execute()
val values = sheet.getValues()
values.map { //row 별로 가져오는 코드
it.map { // 각 라인의 컬럼별로 가져오는 코드
print(it)
print(",")
}
println("-----")
}
}
}