Web開発ログ | エンジニアに役立つ情報 | 開発の中での気づきを発信

高卒Devlog

【yeka/zip】Golangでパスワード付きZipを生成

thumbnail

こんにちは! RYOTAです!

当記事をご覧くださりありがとうございます!

今回はGolangを用いてCSVをZip化しパスワードをかける処理をご紹介します!

はじめに

業務でGo言語を使ってCSVの生成とZip化+パスワードの処理を行いましたので、そちらの実装方法を紹介していきます。
Go言語でCSV出力がしたい!って方は是非最後までご覧の上、ご自身でも試してみてください!
今回使用するライブラリは下記の通りです!

  • jszwec/csvutil

GitHub - jszwec/csvutil: csvutil provides fast and idiomatic mapping between CSV and Go (golang) values. csvutil provides fast and idiomatic mapping between CSV and Go (golang) values. - GitHub - jszwec/csvutil: csvutil provides fast and idiomatic mapping between CSV and Go (golang) values. GitHub

  • yeka/zip

GitHub - yeka/zip: Fork of Go's archive/zip to add reading/writing of password protected zip files. Fork of Go's archive/zip to add reading/writing of password protected zip files. - GitHub - yeka/zip: Fork of Go's archive/zip to add reading/writing of password protected zip files. GitHub

実装方法

ライブラリのインストール

$ go get -u github.com/jszwec/csvutil
$ go get -u github.com/yeka/zip  

インポート

import (
	"os"

	"github.com/gocarina/gocsv"
	// 追加
	"github.com/jszwec/csvutil"
	"github.com/yeka/zip"
	// 追加
)

Zip生成

ここからがメインの処理です。
まずはCSVのデータをバイナリデータに変換します。

contents, err := csvutil.Marshal(csvTest)
if err != nil {
	return err
}

続いて空のZipファイルを生成します。

fzip, err := os.Create("./csv/test.zip")
if err != nil {
	log.Fatalln(err)
}

データの準備が完了したらライターを作成しZipにパスワードをかけて暗号化します。

// Zip ライター作成
zipw := zip.NewWriter(fzip)

// Zip 暗号化
w, err := zipw.Encrypt("test.csv", "test", zip.AES256Encryption)
if err != nil {
	log.Fatal(err)
}

暗号化が出来たらバイナリ化したデータをZipにデータを書き込んで再度にZipを閉じます。

// Zip データ書き込み
_, err = io.Copy(w, bytes.NewReader(contents))
if err != nil {
	log.Fatal(err)
}
zipw.Close()

完成形

CSV出力 + Zip生成の実装は以上で完成となります。
ソースコードは下記の通りです。

package main

import (
	"bytes"
	"io"
	"log"
	"os"

	"github.com/gocarina/gocsv"
	"github.com/yeka/zip"

	// 追加
	"github.com/jszwec/csvutil"
	// 追加
)

type ArrayTest struct {
	Id   int
	Name string
}

type CsvTest struct {
	Id   int    `csv:id`
	Name string `csv:name`
}

func main() {
	testArray := []ArrayTest{
		{Id: 1, Name: "test1"},
		{Id: 2, Name: "test2"},
		{Id: 3, Name: "test3"},
		{Id: 4, Name: "test4"},
		{Id: 5, Name: "test5"},
	}

	var csvTest []CsvTest
	for _, v := range testArray {
		csvDate := CsvTest{
			Id:   v.Id,
			Name: v.Name,
		}

		csvTest = append(csvTest, csvDate)
	}

	// CSVファイル生成
	file, _ := os.OpenFile("./csv/test.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	defer file.Close()
	gocsv.MarshalFile(csvTest, file)

	// Zip 元データをバイナリに変換
	contents, _ := csvutil.Marshal(csvTest)

	// Zip 空ファイル生成
	fzip, err := os.Create("./csv/test.zip")
	if err != nil {
		log.Fatalln(err)
	}

	// Zip ライター作成
	zipw := zip.NewWriter(fzip)

	// Zip 暗号化
	w, err := zipw.Encrypt("test.csv", "test", zip.AES256Encryption)
	if err != nil {
		log.Fatal(err)
	}

	// Zip データ書き込み
	_, err = io.Copy(w, bytes.NewReader(contents))
	if err != nil {
		log.Fatal(err)
	}
	zipw.Close()
}

実行

テストしてみましょう。

$ go run csv.go


開いてみると実際にパスワードが要求され、パスワードを入力すると開くようになってます!

さいごに

今回はGo言語でCSV出力&Zip化&パスワード追加を実装してみました!
いくつかライブラリを試してみましたがyeka/zip以外だと上手くいかずこちらを採用しました。(私のGo力不足です…)
次回はS3へのアップロード方法をまとめようと思います!
最後までご覧くださりありがとうございます!