决定使用 CPP 库处理 xls 问题
This commit is contained in:
24
lib_cpp/CMakeLists.txt
Normal file
24
lib_cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(xlsx_reader VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
add_subdirectory(third_party/OpenXLSX)
|
||||
|
||||
set(OPENXLSX_STATIC ON CACHE BOOL "Build OpenXLSX as static library")
|
||||
FetchContent_MakeAvailable(OpenXLSX)
|
||||
|
||||
add_library(xlsx_reader SHARED src/xlsx_reader.cpp)
|
||||
|
||||
target_include_directories(xlsx_reader PUBLIC include)
|
||||
|
||||
target_link_libraries(xlsx_reader PRIVATE OpenXLSX::OpenXLSX)
|
||||
|
||||
target_compile_definitions(xlsx_reader PRIVATE XLSX_BUILD_SHARED)
|
||||
28
lib_cpp/include/xlsx_reader.h
Normal file
28
lib_cpp/include/xlsx_reader.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef XLSX_READER_H
|
||||
#define XLSX_READER_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(XLSX_BUILD_SHARED)
|
||||
#define XLSX_API __declspec(dllexport)
|
||||
#else
|
||||
#define XLSX_API __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define XLSX_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define XLSX_API
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
XLSX_API char* xlsx_read_first_sheet(const char* filepath);
|
||||
|
||||
XLSX_API void xlsx_free_string(char* str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
96
lib_cpp/src/xlsx_reader.cpp
Normal file
96
lib_cpp/src/xlsx_reader.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "xlsx_reader.h"
|
||||
|
||||
#include <OpenXLSX/OpenXLSX.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
static std::string jsonEscape(const std::string& s) {
|
||||
std::string out;
|
||||
out.reserve(s.size() + 2);
|
||||
for (char c : s) {
|
||||
switch (c) {
|
||||
case '"': out += "\\\""; break;
|
||||
case '\\': out += "\\\\"; break;
|
||||
case '\n': out += "\\n"; break;
|
||||
case '\t': out += "\\t"; break;
|
||||
case '\r': out += "\\r"; break;
|
||||
default:
|
||||
if (static_cast<unsigned char>(c) < 0x20) {
|
||||
char buf[8];
|
||||
std::snprintf(buf, sizeof(buf), "\\u%04x",
|
||||
static_cast<unsigned char>(c));
|
||||
out += buf;
|
||||
} else {
|
||||
out += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static std::string cellAsString(const OpenXLSX::XLCell& cell) {
|
||||
using namespace OpenXLSX;
|
||||
auto& val = cell.value();
|
||||
switch (val.type()) {
|
||||
case XLValueType::Integer:
|
||||
return std::to_string(val.get<int64_t>());
|
||||
case XLValueType::Float:
|
||||
return std::to_string(val.get<double>());
|
||||
case XLValueType::String:
|
||||
return val.get<std::string>();
|
||||
case XLValueType::Boolean:
|
||||
return val.get<bool>() ? "true" : "false";
|
||||
case XLValueType::Empty:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" XLSX_API char* xlsx_read_first_sheet(const char* filepath) {
|
||||
if (!filepath) return nullptr;
|
||||
|
||||
try {
|
||||
OpenXLSX::XLDocument doc;
|
||||
doc.open(filepath);
|
||||
|
||||
auto wks = doc.workbook().worksheet(1);
|
||||
|
||||
std::string json;
|
||||
json += '[';
|
||||
|
||||
bool firstRow = true;
|
||||
for (auto& row : wks.rows()) {
|
||||
if (!firstRow) json += ',';
|
||||
json += '[';
|
||||
|
||||
bool firstCell = true;
|
||||
for (auto& cell : row.cells()) {
|
||||
if (!firstCell) json += ',';
|
||||
json += '"';
|
||||
json += jsonEscape(cellAsString(cell));
|
||||
json += '"';
|
||||
firstCell = false;
|
||||
}
|
||||
|
||||
json += ']';
|
||||
firstRow = false;
|
||||
}
|
||||
|
||||
json += ']';
|
||||
doc.close();
|
||||
|
||||
char* result = static_cast<char*>(std::malloc(json.size() + 1));
|
||||
if (result) {
|
||||
std::memcpy(result, json.c_str(), json.size() + 1);
|
||||
}
|
||||
return result;
|
||||
} catch (const std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" XLSX_API void xlsx_free_string(char* str) {
|
||||
std::free(str);
|
||||
}
|
||||
Reference in New Issue
Block a user