Go Lang/Study

[GoLang] xls 파일을 xlsx 파일로 바꿔주자

DSeung 2023. 9. 17. 18:18

개요

go에 특정 라이브러리는 xlsx만을 지원하기도 하더라고요

일일이 바꿔주자니 하루에 변환할 수 있는 파일 개수에 제한이 걸려있는 사이트가 대부분이더군요

 

그래서 xls을 xlsx로 자동으로 바꿔주는 걸 만들어봅시다

 

(결과물)

 

코드

폴더 계층도는 다음과 같습니다.

resources/xls 폴더는 xlsx로 바꿀 xls 파일을 넣어주고 resources/xlsx는 폴더만 만들어두면 됩니다.

사용한 라이브러리는 다음과 같습니다.

go get github.com/360EntSecGroup-Skylar/excelize
go get github.com/extrame/xls

 

main.go

package main

import (
	"xls-to-xlsx-convertor.com/xlstoXlsx"
)

const xlsDirPath = "resources/xls"
const xlsxDirPath = "resources/xlsx"

func main() {
	// xls 경로랑 xlsx 경로 전달
	xlstoXlsx.FileConversion(xlsDirPath, xlsxDirPath)
}

utils/utils.go

package utils

import "log"

var logFn = log.Panic

// HandleErr : 간단하게 에러 처리
func HandleErr(err error) {
	if err != nil {
		logFn(err)
	}
}

xlsToXlsx/functions.go

package xlsToXlsx

import (
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/extrame/xls"
	"log"
	"os"
	"xls-to-xlsx-convertor.com/utils"
)

// FileConversion : xlsDirPath 경로에 파일들을 xlsx 로 바꿔서 xlsxDirPath 에 저장
func FileConversion(xlsDirPath string, xlsxDirPath string) {
	fileNames := getFileNames(xlsDirPath)

	for _, file := range fileNames {
		var data [][]string
		var arr []string

		// Excel 파일 열기
		xlsFile, err := xls.Open(file.path, "utf-8")
		if err != nil {
			log.Fatalf("엑셀 파일 열기 실패: %v", err)
		}

		for sheet := 0; sheet < xlsFile.NumSheets(); sheet++ {
			sheet := xlsFile.GetSheet(sheet)
			// 행 순회
			for rowIdx := 0; rowIdx <= int(sheet.MaxRow); rowIdx++ {
				row := sheet.Row(rowIdx)
				data = append(data, arr)
				if row != nil {
					// 열 순회
					for colIdx := 0; colIdx < row.LastCol(); colIdx++ {
						cell := row.Col(colIdx)
						data[rowIdx] = append(data[rowIdx], cell)
					}
				}
			}
		}
		utils.HandleErr(createXLSXFile(data, xlsxDirPath+"/"+file.name+"x"))
	}
}

type file struct {
	path string
	name string
}

// getFileNames : dirPath 에 있는 파일 가져오기
func getFileNames(dirPath string) []file {
	var fileNames []file

	// 폴더 열기
	dir, err := os.Open(dirPath)
	utils.HandleErr(err)
	defer func(dir *os.File) {
		err := dir.Close()
		utils.HandleErr(err)
	}(dir)

	// 디렉토리 내 파일 목록 읽기
	fileInfos, err := dir.Readdir(-1)
	utils.HandleErr(err)

	// 파일 이름을 리스트에 넣기
	for _, fileInfo := range fileInfos {
		if !fileInfo.IsDir() {
			fileNames = append(fileNames, file{
				name: fileInfo.Name(),
				path: dirPath + "/" + fileInfo.Name(),
			})
		}
	}

	return fileNames
}

// createXLSXFile : XLS 파일 만들기
func createXLSXFile(data [][]string, fileName string) error {
	// 파일 생성
	file := excelize.NewFile()

	for rowIndex, row := range data {
		for colIndex, cellValue := range row {
			// A1와 같은 형태로 문자열을 생성함
			cellPosition := excelize.ToAlphaString(colIndex) + fmt.Sprintf("%d", rowIndex+1)
			file.SetCellValue("Sheet1", cellPosition, cellValue)
		}
	}

	// 시트 저장
	if err := file.SaveAs(fileName); err != nil {
		return err
	}
	return nil
}

 

더미 파일

저는 다음과 같은 1~4호선의 xls 파일을 사용했습니다.

 

1호선.xls
0.06MB
2호선.xls
0.05MB
3호선.xls
0.05MB
4호선.xls
0.05MB

 

마무리

오타 및 피드백(개선방안 또는 다른 스타일의 코드)은 언제나 환영입니다.

감사합니다. 

반응형