Руководство
Начало работы
Основным сценарием является считывание файла Excel и считывание значений.
julia> import XLSX
julia> xf = XLSX.readxlsx("myfile.xlsx")
XLSXFile("myfile.xlsx") containing 3 Worksheets
sheetname size range
-------------------------------------------------
mysheet 4x2 A1:B4
othersheet 1x1 A1:A1
named 1x1 B4:B4
julia> XLSX.sheetnames(xf)
3-element Array{String,1}:
"mysheet"
"othersheet"
"named"
julia> sh = xf["mysheet"] # получает ссылку на лист
4×2 XLSX.Worksheet: ["mysheet"](A1:B4)
julia> sh[2, 2] # обращается к элементу B2 (2-я строка, 2-й столбец)
"first"
julia> sh["B2"] # также можно использовать имя ячейки
"first"
julia> sh["A2:B4"] # или диапазон ячеек
3×2 Array{Any,2}:
1 "first"
2 "second"
3 "third"
julia> XLSX.readdata("myfile.xlsx", "mysheet", "A2:B4") # краткая форма записи для всего кода выше
3×2 Array{Any,2}:
1 "first"
2 "second"
3 "third"
julia> sh[:] # все данные внутри измерения листа
4×2 Array{Any,2}:
"HeaderA" "HeaderB"
1 "first"
2 "second"
3 "third"
julia> xf["mysheet!A2:B4"] # вы также можете запрашивать значения с помощью ссылки на лист
3×2 Array{Any,2}:
1 "first"
2 "second"
3 "third"
julia> xf["NAMED_CELL"] # можно считывать даже именованные диапазоны
"B4 is a named cell from sheet \"named\""
julia> xf["mysheet!A:B"] # Поддерживаются также диапазоны столбцов
4×2 Array{Any,2}:
"HeaderA" "HeaderB"
1 "first"
2 "second"
3 "third"
Для проверки внутреннего представления каждой ячейки используйте метод getcell
или getcellrange
.
В приведенном выше примере для открытия файла использовалось выражение xf = XLSX.readxlsx(filename)
, поэтому все содержимое файла получается с диска одновременно.
Для считывания содержимого файла по мере необходимости можно использовать функцию XLSX.openxlsx
(см. раздел Чтение больших файлов Excel и кэширование).
Типы данных
Для работы с файлами XLSX этот пакет использует следующие конкретные типы.
#
XLSX.CellValueType
— Type
CellValueType
Конкретные поддерживаемые типы данных.
Union{String, Missing, Float64, Int, Bool, Dates.Date, Dates.Time, Dates.DateTime}
-
Их абстрактные типы преобразовываются в соответствующие конкретные типы во время записи.
-
Значения
Nothing
во время записи преобразовываются вMissing
.
Чтение табличных данных
Метод XLSX.gettable
возвращает табличные данные из электронной таблицы в виде структуры XLSX.DataTable
, которая реализует интерфейс Tables.jl
. Ее можно использовать для создания объекта DataFrame
из DataFrames.jl. Описание дополнительных параметров см. в docstring метода gettable
.
Существует также вспомогательный метод XLSX.readtable
для считывания данных из файла напрямую, как показано в следующем примере.
julia> using DataFrames, XLSX
julia> df = DataFrame(XLSX.readtable("myfile.xlsx", "mysheet"))
3×2 DataFrames.DataFrame
│ Row │ HeaderA │ HeaderB │
├─────┼─────────┼──────────┤
│ 1 │ 1 │ "first" │
│ 2 │ 2 │ "second" │
│ 3 │ 3 │ "third" │
Чтение ячеек в виде матрицы Julia
Для считывания содержимого в виде матрицы Julia используйте функцию XLSX.readdata
или XLSX.getdata
.
julia> import XLSX
julia> m = XLSX.readdata("myfile.xlsx", "mysheet!A1:B3")
3×2 Array{Any,2}:
"HeaderA" "HeaderB"
1 "first"
2 "second"
Индексирование в Worksheet
приведет к диспетчеризации в метод XLSX.getdata
.
julia> xf = XLSX.readxlsx("myfile.xlsx")
XLSXFile("myfile.xlsx") containing 3 Worksheets
sheetname size range
-------------------------------------------------
mysheet 4x2 A1:B4
othersheet 1x1 A1:A1
named 1x1 B4:B4
julia> xf["mysheet!A1:B3"]
3×2 Array{Any,2}:
"HeaderA" "HeaderB"
1 "first"
2 "second"
julia> sheet = xf["mysheet"]
4×2 XLSX.Worksheet: ["mysheet"](A1:B4)
julia> sheet["A1:B3"]
3×2 Array{Any,2}:
"HeaderA" "HeaderB"
1 "first"
2 "second"
Однако индексирование в одной ячейке приведет к возврату отдельного значения, а не матрицы.
julia> sheet["A1"]
"HeaderA"
Если нужный диапазон заранее не известен, можно воспользоваться методами XLSX.readtable
и XLSX.gettable
.
julia> dtable = XLSX.readtable("myfile.xlsx", "mysheet")
XLSX.DataTable(Any[Any[1, 2, 3], Any["first", "second", "third"]], [:HeaderA, :HeaderB], Dict(:HeaderB => 2, :HeaderA => 1))
julia> m = hcat(dtable.data...)
3×2 Matrix{Any}:
1 "first"
2 "second"
3 "third"
Чтение больших файлов Excel и кэширование
У метода XLSX.openxlsx
есть параметр enable_cache
, который управляет кэшированием ячеек листа.
Кэш включен по умолчанию, поэтому если ячейка листа считывается дважды, вместо чтения с диска во второй раз используется кэшированное значение.
Если enable_cache=false
, ячейки листа будут всегда считываться с диска. Рекомендуется использовать, если требуется считать таблицу, которая не помещается в памяти.
В следующем примере показано чтение ячеек листа по одной строке за раз, где myfile.xlsx
является таблицей, которая не помещается в памяти.
julia> XLSX.openxlsx("myfile.xlsx", enable_cache=false) do f
sheet = f["mysheet"]
for r in XLSX.eachrow(sheet)
# r — это `SheetRow`; значения считываются с помощью ссылок на столбцы
rn = XLSX.row_number(r) # номер строки `SheetRow`
v1 = r[1] # считывается значение в столбце 1
v2 = r["B"] # считывается значение в столбце 2
println("v1=$v1, v2=$v2")
end
end
v1=HeaderA, v2=HeaderB
v1=1, v2=first
v1=2, v2=second
v1=3, v2=third
Табличные данные можно также передавать в потоковом режиме с помощью функции XLSX.eachtablerow(sheet)
, которая является базовым итератором в методе gettable
. Описание дополнительных параметров см. в docstring функции XLSX.eachtablerow
.
julia> XLSX.openxlsx("myfile.xlsx", enable_cache=false) do f
sheet = f["mysheet"]
for r in XLSX.eachtablerow(sheet)
# r - это`TableRow`; значения считываются с помощью заголовков или номеров столбцов
rn = XLSX.row_number(r) # номер строки `TableRow`
v1 = r[1] # считывается значение в столбце 1 таблицы
v2 = r[:HeaderB] # считывается значение в столбце с заголовком `:HeaderB`
println("v1=$v1, v2=$v2")
end
end
v1=1, v2=first
v1=2, v2=second
v1=3, v2=third
Запись файлов Excel
Создание новых файлов
При открытии файла в режиме write
с помощью функции XLSX.openxlsx
для редактирования открывается новый (пустой) файл Excel.
XLSX.openxlsx("my_new_file.xlsx", mode="w") do xf
sheet = xf[1]
XLSX.rename!(sheet, "new_sheet")
sheet["A1"] = "this"
sheet["A2"] = "is a"
sheet["A3"] = "new file"
sheet["A4"] = 100
# добавляем строку с A5 по E5
sheet["A5"] = collect(1:5) # эквивалентно `sheet["A5", dim=2] = collect(1:4)`
# добавляем столбец с B1 по B4
sheet["B1", dim=1] = collect(1:4)
# добавляем матрицу с A7 по C9
sheet["A7:C9"] = [ 1 2 3 ; 4 5 6 ; 7 8 9 ]
end
Редактирование существующих файлов
При открытии файла в режиме read-write
с помощью функции XLSX.openxlsx
для редактирования открывается существующий файл Excel. Данные, имеющиеся в исходном файле, сохраняются.
XLSX.openxlsx("my_new_file.xlsx", mode="rw") do xf
sheet = xf[1]
sheet["B1"] = "new data"
end
Известно, что режим |
Экспорт табличных данных из электронной таблицы
При наличии ссылки на лист используйте метод XLSX.writetable!
. Базовой ячейкой по умолчанию является ячейка "A1"
.
using XLSX, Test
filename = "myfile.xlsx"
columns = Vector()
push!(columns, [1, 2, 3])
push!(columns, ["a", "b", "c"])
labels = [ "column_1", "column_2"]
XLSX.openxlsx(filename, mode="w") do xf
sheet = xf[1]
XLSX.writetable!(sheet, columns, labels, anchor_cell=XLSX.CellRef("B2"))
end
# считываем данные обратно
XLSX.openxlsx(filename) do xf
sheet = xf[1]
@test sheet["B2"] == "column_1"
@test sheet["C2"] == "column_2"
@test sheet["B3"] == 1
@test sheet["B4"] == 2
@test sheet["B5"] == 3
@test sheet["C3"] == "a"
@test sheet["C4"] == "b"
@test sheet["C5"] == "c"
end
Для записи напрямую в новый файл можно также использовать функцию XLSX.writetable
(см. следующий раздел).
Экспорт табличных данных из любого источника, совместимого с Tables.jl
Для экспорта табличных данных в Excel используйте метод XLSX.writetable
, который принимает либо столбцы и имена столбцов, либо любую таблицу Tables.jl
.
julia> using Dates
julia> import DataFrames, XLSX
julia> df = DataFrames.DataFrame(integers=[1, 2, 3, 4], strings=["Hey", "You", "Out", "There"], floats=[10.2, 20.3, 30.4, 40.5], dates=[Date(2018,2,20), Date(2018,2,21), Date(2018,2,22), Date(2018,2,23)], times=[Dates.Time(19,10), Dates.Time(19,20), Dates.Time(19,30), Dates.Time(19,40)], datetimes=[Dates.DateTime(2018,5,20,19,10), Dates.DateTime(2018,5,20,19,20), Dates.DateTime(2018,5,20,19,30), Dates.DateTime(2018,5,20,19,40)])
4×6 DataFrames.DataFrame
│ Row │ integers │ strings │ floats │ dates │ times │ datetimes │
├─────┼──────────┼─────────┼────────┼────────────┼──────────┼─────────────────────┤
│ 1 │ 1 │ Hey │ 10.2 │ 2018-02-20 │ 19:10:00 │ 2018-05-20T19:10:00 │
│ 2 │ 2 │ You │ 20.3 │ 2018-02-21 │ 19:20:00 │ 2018-05-20T19:20:00 │
│ 3 │ 3 │ Out │ 30.4 │ 2018-02-22 │ 19:30:00 │ 2018-05-20T19:30:00 │
│ 4 │ 4 │ There │ 40.5 │ 2018-02-23 │ 19:40:00 │ 2018-05-20T19:40:00 │
julia> XLSX.writetable("df.xlsx", df)
Вы также можете экспортировать в Excel несколько таблиц, каждая из которых будет на отдельном листе, передав в именованном аргументе либо кортеж (из столбцов и их имен) для каждого имени листа, либо список пар "sheet name" => table
для любого совместимого источника Tables.jl.
julia> import DataFrames, XLSX
julia> df1 = DataFrames.DataFrame(COL1=[10,20,30], COL2=["Fist", "Sec", "Third"])
3×2 DataFrames.DataFrame
│ Row │ COL1 │ COL2 │
├─────┼──────┼───────┤
│ 1 │ 10 │ Fist │
│ 2 │ 20 │ Sec │
│ 3 │ 30 │ Third │
julia> df2 = DataFrames.DataFrame(AA=["aa", "bb"], AB=[10.1, 10.2])
2×2 DataFrames.DataFrame
│ Row │ AA │ AB │
├─────┼────┼──────┤
│ 1 │ aa │ 10.1 │
│ 2 │ bb │ 10.2 │
julia> XLSX.writetable("report.xlsx", "REPORT_A" => df1, "REPORT_B" => df2)
В этом последнем примере показано, как сделать то же самое, но если вы заранее не знаете, сколько таблиц будет экспортироваться.
df1 = DataFrame(A=[1,2], B=[3,4])
df2 = DataFrame(C=["Hey", "you"], D=["out", "there"])
sheet_names = [ "1st", "2nd" ]
dataframes = [ df1, df2 ]
@assert length(sheet_names) == length(dataframes)
XLSX.openxlsx("report.xlsx", mode="w") do xf
for i in eachindex(sheet_names)
sheet_name = sheet_names[i]
df = dataframes[i]
if i == firstindex(sheet_names)
sheet = xf[1]
XLSX.rename!(sheet, sheet_name)
XLSX.writetable!(sheet, df)
else
sheet = XLSX.addsheet!(xf, sheet_name)
XLSX.writetable!(sheet, df)
end
end
end
Интерфейс Tables.jl
Оба типа — XLSX.DataTable
и XLSX.TableRowIterator
— соответствуют требованиям интерфейса Tables.jl. Экземпляр XLSX.TableRowIterator
создается функцией XLSX.eachtablerow
.
Кроме того, XLSX.writetable
принимает аргумент, который соответствует требованиям интерфейса Tables.jl
.
Например, тип DataFrame
из пакета DataFrames поддерживает интерфейс Tables.jl
. Следующий код записывает объект DataFrame
в файл Excel и снова считывает его.
julia> using Dates
julia> import DataFrames, XLSX
julia> df = DataFrames.DataFrame(integers=[1, 2, 3, 4], strings=["Hey", "You", "Out", "There"], floats=[10.2, 20.3, 30.4, 40.5], dates=[Date(2018,2,20), Date(2018,2,21), Date(2018,2,22), Date(2018,2,23)], times=[Dates.Time(19,10), Dates.Time(19,20), Dates.Time(19,30), Dates.Time(19,40)], datetimes=[Dates.DateTime(2018,5,20,19,10), Dates.DateTime(2018,5,20,19,20), Dates.DateTime(2018,5,20,19,30), Dates.DateTime(2018,5,20,19,40)])
4×6 DataFrames.DataFrame
│ Row │ integers │ strings │ floats │ dates │ times │ datetimes │
│ │ Int64 │ String │ Float64 │ Date │ Time │ DateTime │
├─────┼──────────┼─────────┼─────────┼────────────┼──────────┼─────────────────────┤
│ 1 │ 1 │ Hey │ 10.2 │ 2018-02-20 │ 19:10:00 │ 2018-05-20T19:10:00 │
│ 2 │ 2 │ You │ 20.3 │ 2018-02-21 │ 19:20:00 │ 2018-05-20T19:20:00 │
│ 3 │ 3 │ Out │ 30.4 │ 2018-02-22 │ 19:30:00 │ 2018-05-20T19:30:00 │
│ 4 │ 4 │ There │ 40.5 │ 2018-02-23 │ 19:40:00 │ 2018-05-20T19:40:00 │
julia> XLSX.writetable("output_table.xlsx", df, overwrite=true, sheetname="report", anchor_cell="B2")
julia> f = XLSX.readxlsx("output_table.xlsx")
XLSXFile("output_table.xlsx") containing 1 Worksheet
sheetname size range
-------------------------------------------------
report 6x7 A1:G6
julia> s = f["report"]
6×7 XLSX.Worksheet: ["report"](A1:G6)
julia> df2 = XLSX.eachtablerow(s) |> DataFrames.DataFrame
4×6 DataFrames.DataFrame
│ Row │ integers │ strings │ floats │ dates │ times │ datetimes │
│ │ Int64 │ String │ Float64 │ Date │ Time │ DateTime │
├─────┼──────────┼─────────┼─────────┼────────────┼──────────┼─────────────────────┤
│ 1 │ 1 │ Hey │ 10.2 │ 2018-02-20 │ 19:10:00 │ 2018-05-20T19:10:00 │
│ 2 │ 2 │ You │ 20.3 │ 2018-02-21 │ 19:20:00 │ 2018-05-20T19:20:00 │
│ 3 │ 3 │ Out │ 30.4 │ 2018-02-22 │ 19:30:00 │ 2018-05-20T19:30:00 │
│ 4 │ 4 │ There │ 40.5 │ 2018-02-23 │ 19:40:00 │ 2018-05-20T19:40:00 │