mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
commit
fc1d73fee2
|
@ -10,7 +10,14 @@ environment:
|
|||
- STATIC: ON
|
||||
|
||||
init: []
|
||||
install: []
|
||||
install:
|
||||
- git clone https://github.com/Microsoft/vcpkg
|
||||
- cd vcpkg
|
||||
- powershell -exec bypass scripts\bootstrap.ps1
|
||||
- vcpkg install cryptopp zlib
|
||||
- vcpkg integrate install
|
||||
- cd ..
|
||||
|
||||
before_build:
|
||||
- git submodule update --init
|
||||
- cmake -H. -Bbuild -G"Visual Studio 14 2015 Win64" -DSTATIC=%STATIC% -DSAMPLES=ON -DBENCHMARKS=ON
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -3,3 +3,6 @@
|
|||
url = http://scm.codesynthesis.com/libstudxml/libstudxml.git
|
||||
branch = master
|
||||
ignore = dirty
|
||||
[submodule "third-party/cxxtest"]
|
||||
path = third-party/cxxtest
|
||||
url = https://github.com/CxxTest/cxxtest
|
||||
|
|
|
@ -17,7 +17,7 @@ matrix:
|
|||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-6
|
||||
- g++-6 zlib1g libcrypto++6 libcrypto++-dbg libcrypto++-dev
|
||||
env:
|
||||
- COMPILER=g++-6
|
||||
- COVERAGE=OFF
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/common.cmake)
|
||||
project(${LIBRARY_NAME}.benchmarks VERSION ${LIBRARY_VERSION} LANGUAGES CXX)
|
||||
project(xlnt.benchmarks)
|
||||
|
||||
if(NOT COMBINED_PROJECT)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
add_subdirectory(${LIBRARY_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBRARY_INCLUDE_DIR})
|
||||
|
||||
file(GLOB SAMPLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
|
||||
if(NOT MSVC)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
foreach(SAMPLE_SOURCE IN ITEMS ${SAMPLE_SOURCES})
|
||||
get_filename_component(SAMPLE_NAME ${SAMPLE_SOURCE} NAME_WE)
|
||||
set(SAMPLE_EXECUTABLE benchmark-${SAMPLE_NAME})
|
||||
add_executable(${SAMPLE_EXECUTABLE} ${SAMPLE_SOURCE})
|
||||
target_link_libraries(${SAMPLE_EXECUTABLE} ${LIBRARY_NAME})
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(${SAMPLE_EXECUTABLE} Threads::Threads)
|
||||
endif()
|
||||
target_link_libraries(${SAMPLE_EXECUTABLE} xlnt)
|
||||
endforeach()
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data
|
||||
|
|
|
@ -827,6 +827,11 @@ private:
|
|||
/// </summary>
|
||||
void garbage_collect_formulae();
|
||||
|
||||
/// <summary>
|
||||
/// Update extended workbook properties titlesOfParts and headingPairs when sheets change.
|
||||
/// </summary>
|
||||
void update_sheet_properties();
|
||||
|
||||
/// <summary>
|
||||
/// An opaque pointer to a structure that holds all of the data relating to this workbook.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,28 +1,22 @@
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/common.cmake)
|
||||
project(${LIBRARY_NAME}.samples VERSION ${LIBRARY_VERSION} LANGUAGES CXX C)
|
||||
project(xlnt.samples)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(NOT COMBINED_PROJECT)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
add_subdirectory(${LIBRARY_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBRARY_INCLUDE_DIR})
|
||||
|
||||
file(GLOB SAMPLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
|
||||
if(NOT MSVC)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
foreach(SAMPLE_SOURCE IN ITEMS ${SAMPLE_SOURCES})
|
||||
get_filename_component(SAMPLE_NAME ${SAMPLE_SOURCE} NAME_WE)
|
||||
set(SAMPLE_EXECUTABLE sample-${SAMPLE_NAME})
|
||||
add_executable(${SAMPLE_EXECUTABLE} ${SAMPLE_SOURCE})
|
||||
target_link_libraries(${SAMPLE_EXECUTABLE} ${LIBRARY_NAME})
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(${SAMPLE_EXECUTABLE} Threads::Threads)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data
|
||||
|
|
|
@ -490,8 +490,11 @@ std::string cell::formula() const
|
|||
|
||||
void cell::clear_formula()
|
||||
{
|
||||
if (has_formula())
|
||||
{
|
||||
d_->formula_.clear();
|
||||
worksheet().garbage_collect_formulae();
|
||||
}
|
||||
}
|
||||
|
||||
void cell::error(const std::string &error)
|
||||
|
|
|
@ -57,6 +57,9 @@ struct workbook_impl
|
|||
stylesheet_(other.stylesheet_),
|
||||
manifest_(other.manifest_),
|
||||
theme_(other.theme_),
|
||||
core_properties_(other.core_properties_),
|
||||
extended_properties_(other.extended_properties_),
|
||||
custom_properties_(other.custom_properties_),
|
||||
view_(other.view_),
|
||||
code_name_(other.code_name_),
|
||||
file_version_(other.file_version_)
|
||||
|
@ -78,6 +81,10 @@ struct workbook_impl
|
|||
code_name_ = other.code_name_;
|
||||
file_version_ = other.file_version_;
|
||||
|
||||
core_properties_ = other.core_properties_;
|
||||
extended_properties_ = other.extended_properties_;
|
||||
custom_properties_ = other.custom_properties_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <detail/constants.hpp>
|
||||
|
@ -50,7 +51,7 @@ enum class hash_algorithm
|
|||
whirlpool
|
||||
};
|
||||
|
||||
struct crypto_helper
|
||||
struct XLNT_API crypto_helper
|
||||
{
|
||||
static const std::size_t segment_length;
|
||||
|
||||
|
|
|
@ -252,6 +252,11 @@ void xlsx_producer::write_property(const std::string &name, const variant &value
|
|||
write_start_element(constants::ns("vt"), "lpwstr");
|
||||
}
|
||||
|
||||
if (!custom && ns == constants::ns("dcterms") && (name == "created" || name == "modified"))
|
||||
{
|
||||
write_attribute(xml::qname(constants::ns("xsi"), "type"), "dcterms:W3CDTF");
|
||||
}
|
||||
|
||||
write_characters(value.get<std::string>());
|
||||
|
||||
if (custom)
|
||||
|
@ -331,6 +336,8 @@ void xlsx_producer::write_core_properties(const relationship &/*rel*/)
|
|||
auto core_properties = source_.core_properties();
|
||||
std::unordered_map<std::string, std::string> namespaces;
|
||||
|
||||
write_namespace(constants::ns("core-properties"), "cp");
|
||||
|
||||
for (const auto &prop : core_properties)
|
||||
{
|
||||
for (const auto &ns : core_property_namespace(prop))
|
||||
|
@ -525,11 +532,6 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
|
||||
write_start_element(xmlns, "sheets");
|
||||
|
||||
if (any_defined_names)
|
||||
{
|
||||
write_element(xmlns, "definedNames", "");
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wrange-loop-analysis"
|
||||
for (const auto ws : source_)
|
||||
|
@ -547,26 +549,25 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
}
|
||||
|
||||
write_attribute(xml::qname(xmlns_r, "id"), sheet_rel_id);
|
||||
|
||||
if (ws.has_auto_filter())
|
||||
{
|
||||
write_start_element(xmlns, "definedName");
|
||||
|
||||
write_attribute("name", "_xlnm._FilterDatabase");
|
||||
write_attribute("hidden", write_bool(true));
|
||||
write_attribute("localSheetId", "0");
|
||||
write_characters(
|
||||
"'" + ws.title() + "'!" + range_reference::make_absolute(ws.auto_filter()).to_string());
|
||||
|
||||
write_end_element(xmlns, "definedName");
|
||||
}
|
||||
|
||||
write_end_element(xmlns, "sheet");
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
write_end_element(xmlns, "sheets");
|
||||
|
||||
if (any_defined_names)
|
||||
{
|
||||
write_start_element(xmlns, "definedNames");
|
||||
/*
|
||||
write_attribute("name", "_xlnm._FilterDatabase");
|
||||
write_attribute("hidden", write_bool(true));
|
||||
write_attribute("localSheetId", "0");
|
||||
write_characters("'" + ws.title() + "'!" +
|
||||
range_reference::make_absolute(ws.auto_filter()).to_string());
|
||||
*/
|
||||
write_end_element(xmlns, "definedNames");
|
||||
}
|
||||
|
||||
if (source_.has_calculation_properties())
|
||||
{
|
||||
write_start_element(xmlns, "calcPr");
|
||||
|
@ -709,6 +710,14 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
void xlsx_producer::write_calculation_chain(const relationship & /*rel*/)
|
||||
{
|
||||
write_start_element(constants::ns("spreadsheetml"), "calcChain");
|
||||
write_namespace(constants::ns("spreadsheetml"), "");
|
||||
/*
|
||||
write_start_element(constants::ns("spreadsheetml"), "c");
|
||||
write_attribute("r", "B2");
|
||||
write_attribute("i", "1");
|
||||
write_attribute("l", "1");
|
||||
write_end_element(constants::ns("spreadsheetml"), "c");
|
||||
*/
|
||||
write_end_element(constants::ns("spreadsheetml"), "calcChain");
|
||||
}
|
||||
|
||||
|
@ -2835,10 +2844,10 @@ void xlsx_producer::write_vml_drawings(const relationship &rel, worksheet ws, co
|
|||
std::vector<std::pair<std::string, std::string>> style;
|
||||
|
||||
style.push_back({"position", "absolute"});
|
||||
style.push_back({"margin-left", std::to_string(comment.left())});
|
||||
style.push_back({"margin-top", std::to_string(comment.top())});
|
||||
style.push_back({"width", std::to_string(comment.width())});
|
||||
style.push_back({"height", std::to_string(comment.height())});
|
||||
style.push_back({"margin-left", std::to_string(comment.left()) + "pt"});
|
||||
style.push_back({"margin-top", std::to_string(comment.top()) + "pt"});
|
||||
style.push_back({"width", std::to_string(comment.width()) + "pt"});
|
||||
style.push_back({"height", std::to_string(comment.height()) + "pt"});
|
||||
style.push_back({"z-index", std::to_string(comment_index + 1)});
|
||||
style.push_back({"visibility", comment.visible() ? "visible" : "hidden"});
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ public:
|
|||
|
||||
#ifndef __MINGW32__
|
||||
xlnt::workbook wb2;
|
||||
const auto path = U8STRING_LITERAL(XLNT_TEST_DATA_DIR) u8"/9_unicode_filename_Λ.xlsx";
|
||||
wb2.load(path);
|
||||
const auto path2 = U8STRING_LITERAL(XLNT_TEST_DATA_DIR) u8"/9_unicode_filename_Λ.xlsx";
|
||||
wb2.load(path2);
|
||||
TS_ASSERT_EQUALS(wb2.active_sheet().cell("A1").value<std::string>(), "unicode!");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
|
||||
std::vector<std::uint8_t> destination;
|
||||
source_workbook.save(destination);
|
||||
source_workbook.save("temp.xlsx");
|
||||
|
||||
std::ifstream source_stream(source.string(), std::ios::binary);
|
||||
|
||||
|
@ -45,7 +46,7 @@ public:
|
|||
return xml_helper::xlsx_archives_match(source_decrypted, destination);
|
||||
}
|
||||
|
||||
void test_round_trip_empty_excel_rw()
|
||||
void test_round_trip_rw()
|
||||
{
|
||||
const auto files = std::vector<std::string>
|
||||
{
|
||||
|
@ -64,7 +65,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void test_round_trip_empty_excel_rw_encrypted()
|
||||
void test_round_trip_rw_encrypted()
|
||||
{
|
||||
const auto files = std::vector<std::string>
|
||||
{
|
||||
|
|
|
@ -759,6 +759,8 @@ worksheet workbook::create_sheet()
|
|||
workbook_rel.target(), relationship_type::worksheet, relative_sheet_uri, target_mode::internal);
|
||||
d_->sheet_title_rel_id_map_[title] = ws_rel;
|
||||
|
||||
update_sheet_properties();
|
||||
|
||||
return worksheet(&d_->worksheets_.back());
|
||||
}
|
||||
|
||||
|
@ -1007,9 +1009,10 @@ void workbook::remove_sheet(worksheet ws)
|
|||
}
|
||||
|
||||
auto ws_rel_id = d_->sheet_title_rel_id_map_.at(ws.title());
|
||||
auto wb_rel = d_->manifest_.relationship(xlnt::path("/"), xlnt::relationship_type::office_document);
|
||||
auto wb_rel = d_->manifest_.relationship(path("/"), xlnt::relationship_type::office_document);
|
||||
auto ws_rel = d_->manifest_.relationship(wb_rel.target().path(), ws_rel_id);
|
||||
d_->manifest_.unregister_override_type(ws_rel.target().path());
|
||||
auto ws_part = d_->manifest_.canonicalize({wb_rel, ws_rel}).resolve(path("/"));
|
||||
d_->manifest_.unregister_override_type(ws_part);
|
||||
auto rel_id_map = d_->manifest_.unregister_relationship(wb_rel.target(), ws_rel_id);
|
||||
d_->sheet_title_rel_id_map_.erase(ws.title());
|
||||
d_->worksheets_.erase(match_iter);
|
||||
|
@ -1020,6 +1023,8 @@ void workbook::remove_sheet(worksheet ws)
|
|||
title_rel_id_pair.second = rel_id_map.count(title_rel_id_pair.second) > 0
|
||||
? rel_id_map[title_rel_id_pair.second] : title_rel_id_pair.second;
|
||||
}
|
||||
|
||||
update_sheet_properties();
|
||||
}
|
||||
|
||||
worksheet workbook::create_sheet(std::size_t index)
|
||||
|
@ -1054,6 +1059,8 @@ worksheet workbook::create_sheet_with_rel(const std::string &title, const relati
|
|||
workbook_rel.target(), relationship_type::worksheet, rel.target(), target_mode::internal);
|
||||
d_->sheet_title_rel_id_map_[title] = ws_rel;
|
||||
|
||||
update_sheet_properties();
|
||||
|
||||
return worksheet(&d_->worksheets_.back());
|
||||
}
|
||||
|
||||
|
@ -1499,4 +1506,18 @@ void workbook::garbage_collect_formulae()
|
|||
}
|
||||
}
|
||||
|
||||
void workbook::update_sheet_properties()
|
||||
{
|
||||
if (has_extended_property(extended_property::titles_of_parts))
|
||||
{
|
||||
extended_property(extended_property::titles_of_parts, sheet_titles());
|
||||
}
|
||||
|
||||
if (has_extended_property(extended_property::heading_pairs))
|
||||
{
|
||||
extended_property(extended_property::heading_pairs,
|
||||
std::vector<variant>{variant("Worksheets"), variant(static_cast<int>(sheet_count()))});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -275,8 +275,8 @@ void worksheet::title(const std::string &title)
|
|||
throw invalid_sheet_title(title);
|
||||
}
|
||||
|
||||
auto same_title =
|
||||
std::find_if(workbook().begin(), workbook().end(), [&](worksheet ws) { return ws.title() == title; });
|
||||
auto same_title = std::find_if(workbook().begin(), workbook().end(),
|
||||
[&](worksheet ws) { return ws.title() == title; });
|
||||
|
||||
if (same_title != workbook().end() && *same_title != *this)
|
||||
{
|
||||
|
@ -286,6 +286,8 @@ void worksheet::title(const std::string &title)
|
|||
workbook().d_->sheet_title_rel_id_map_[title] = workbook().d_->sheet_title_rel_id_map_[d_->title_];
|
||||
workbook().d_->sheet_title_rel_id_map_.erase(d_->title_);
|
||||
d_->title_ = title;
|
||||
|
||||
workbook().update_sheet_properties();
|
||||
}
|
||||
|
||||
cell_reference worksheet::frozen_panes() const
|
||||
|
|
|
@ -8,6 +8,10 @@ if(NOT COMBINED_PROJECT)
|
|||
add_subdirectory(${LIBRARY_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
endif()
|
||||
|
||||
set(CXXTEST_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../third-party/cxxtest)
|
||||
set(CXXTEST_PYTHON_TESTGEN_EXECUTABLE ${CXXTEST_ROOT_DIR}/bin/cxxtestgen)
|
||||
set(CXXTEST_INCLUDE_DIR ${CXXTEST_ROOT_DIR})
|
||||
|
||||
file(GLOB CELL_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../source/cell/tests/test_*.hpp)
|
||||
file(GLOB CHARTS_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../source/charts/tests/test_*.hpp)
|
||||
file(GLOB CHARTSHEET_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../source/chartsheet/tests/test_*.hpp)
|
||||
|
@ -73,10 +77,9 @@ else()
|
|||
endif()
|
||||
|
||||
find_package(PythonInterp REQUIRED)
|
||||
find_package(CxxTest REQUIRED)
|
||||
|
||||
add_custom_command(OUTPUT ${RUNNER}
|
||||
COMMAND ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --runner=ErrorPrinter -o ${RUNNER} ${TESTS}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --runner=ErrorPrinter -o ${RUNNER} ${TESTS}
|
||||
DEPENDS ${TESTS}
|
||||
COMMENT "Generating test runner ${RUNNER}")
|
||||
|
||||
|
|
6
third-party/CMakeLists.txt
vendored
6
third-party/CMakeLists.txt
vendored
|
@ -2,10 +2,6 @@ cmake_minimum_required(VERSION 3.2)
|
|||
project(xlnt.third-party)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(CryptoPP REQUIRED)
|
||||
find_package(CxxTest REQUIRED)
|
||||
|
||||
set(LIBSTUDXML_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libstudxml)
|
||||
|
||||
set(LIBSTUDXML
|
||||
|
@ -24,8 +20,6 @@ set(LIBSTUDXML
|
|||
set(EXPAT
|
||||
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlparse.c
|
||||
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlrole.c
|
||||
# ${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok_impl.c
|
||||
# ${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok_ns.c
|
||||
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok.c
|
||||
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/ascii.h
|
||||
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/asciitab.h
|
||||
|
|
1
third-party/cxxtest
vendored
Submodule
1
third-party/cxxtest
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 191adddb3876ab389c0c856e1c03874bf70f8ee4
|
Loading…
Reference in New Issue
Block a user