Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

最近の作業部屋活動履歴

2023-04-16
2023-03-24
2023-03-22
2023-01-25

最近のWikiの更新 (Recent Changes)

2023-04-16
2023-03-24
2023-01-25
2023-01-08
2023-01-07

Wikiガイド(Guide)

サイドバー (Side Bar)

Excelファイル読み込みライブラリ xlsxio VS2012ビルド対応

概要

以前、Excel ファイル(拡張子 .xlsx) を作成できる C言語のライブラリ libxlsxwriter を紹介しましたが、書けるのであれば読み込みもしたい、 ということで、読み込みできるライブラリを探したところ、xlsxio を見つけました。libxlsxwriter同様、C言語のライブラリです。 C99仕様になっているためか、そのままでは Visual Studio 2012 でビルドできませんでしたので少し書き換えてビルドが通るようにしました。 何か処理をした後に変数の宣言をしていたりするところのビルドを通せるように、ソースの拡張子を cppに変える、といった処置をしています。 (そろそろ使うVisualStudioのバージョンを上げようかな・・・さすがにもう古い気が・・・)

ついでに、元々入っていたサンプルプログラム xlsxio_read_main を書き換えて、 Excelデータを読み込み STL の map に格納するプログラム myxlsxio_read_main.cpp を作りました。

依存ライブラリ

下記ソースzipの中に全て入れてあります。ライセンスはそれぞれのソースディレクトリ内にある README、COPYING 等を参照してください。minizip は libxlsxwriter のリポジトリに入っていたものを流用しました。

  • expat
  • minizip
  • zlib

ソース

myxlsxio_read_main.cpp 内容

#include <cstdlib>
#include <cstdio>
#include <cstring>

#include <vector>
#include <map>
#include <string>

#include "xlsxio_read.h"

typedef std::map<std::pair<size_t, size_t>, std::string> sheet_type;
typedef std::vector<std::pair<std::string, sheet_type>> sheets_type;

int main (int argc, char* argv[]) {
	if (argc == 1) return 0;
	xlsxioreader xlsxioread;
	if (!(xlsxioread = xlsxioread_open(argv[1]))){
		printf("file open error.\n");
		return 1;
	}

	sheets_type sheets;

	// list available sheets
	std::fprintf(stderr, "Available sheets:\n");
	xlsxioread_list_sheets(xlsxioread, [](const char* name, void* psheets_ptr){
		((sheets_type*)psheets_ptr)->push_back(std::make_pair(name, sheet_type()));
		std::fprintf(stderr, "%s\n", name);
		return 0;
	}, &sheets);
	std::fprintf(stderr, "Sheets found: %u\n", sheets.size());

	// read ID sheets
	for (size_t i = 0; i < sheets.size(); ++i){
		std::string &name = sheets[i].first;
		std::fprintf(stderr, "[Sheet %s]\n", name.c_str());
		xlsxioread_process(xlsxioread, name.c_str(), XLSXIOREAD_SKIP_ALL_EMPTY,
			[](size_t row, size_t col, const char* value, void* psheet_ptr){
				((sheet_type *)psheet_ptr)->insert(std::make_pair(std::make_pair(row, col), value));
				std::fprintf(stderr, "[%d,%d]:%s\n", (int)row, (int)col, value);
				return 0;
			}, NULL, &sheets[i].second
		);
	}

	//clean up
	xlsxioread_close(xlsxioread);

	// specific process
	const char *filename = argv[1] + std::strlen(argv[1]);
	while(filename > argv[1] && *filename != '\\') --filename; 
	if (*filename == '\\') ++filename;

	for (size_t k = 0; k < sheets.size(); ++k){
		std::string &name = sheets[k].first;
		sheet_type &sheet = sheets[k].second;
		// ここに固有の処理を入れる想定
	}

	return 0;
}

参照