Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write multiple sheets to the same file #38

Open
kafisatz opened this issue Aug 12, 2019 · 1 comment
Open

write multiple sheets to the same file #38

kafisatz opened this issue Aug 12, 2019 · 1 comment

Comments

@kafisatz
Copy link

I can see that the save command supports a sheetname keyword.
However, I understand it is currently not possible to write several sheets into the same Excel file, right?
This would be a nice addition in my view.

@kafisatz
Copy link
Author

@davidanthoff Notably this was actually fairly easy to achieve with pycall (package 'xlsxwriter').
I do not know if my code is worth anything for ExcelFiles, but I paste it here anyways

module ExcelWriter

using DataFrames 
using PyCall

global const pyModnumpy = PyCall.PyNULL()
global const pyModPandas = PyCall.PyNULL()
global const pyModxlsxwriter = PyCall.PyNULL()

function __init__()
	#the following lines may trigger the installation of the respective python packages	
	copy!(pyModnumpy, PyCall.pyimport_conda("numpy","numpy"))
	copy!(pyModPandas, PyCall.pyimport_conda("pandas","pandas"))
	copy!(pyModxlsxwriter, PyCall.pyimport_conda("xlsxwriter","xlsxwriter"))    
end

export ExcelSheet 
mutable struct ExcelSheet
	name::String
	data::DataFrame
end

export ExcelData 
mutable struct ExcelData
	sheets::Array{ExcelSheet,1}
    #charts::Array{Chart,1}
    function ExcelData()
        #return new(Array{ExcelSheet}(undef,0),Array{Chart}(undef,0))
        return new(Array{ExcelSheet}(undef,0))
    end
    function ExcelData(a)
        return  new(a)
    end
    #function ExcelData(a,b)
    #    return  new(a,b)
    #end
end


function create_custom_dict(df::DataFrame)	
	header=names(df)
	d=Dict{AbstractString,Array{Any,1}}()
	for i=1:length(header)			
		d[string(header[i])]=df[!,i]
	end
	return d
end

export writeToExcel 
function writeToExcel(excelData::ExcelData,xlFile::T,write_header::Bool,write_index::Bool) where {T <: AbstractString}
	#writing an Excel file seems very slow if the file already exists!
	isfile(xlFile)&&rm(xlFile)
	
	writer=writeDFtoExcel(excelData,xlFile,0,0,write_header,write_index)
	workbook = writer.book
    #=
		#Plot charts	
		for c in excelData.charts
			sheetWhereChartIsLocated=c.sheet		
			worksheet = writer.sheets[sheetWhereChartIsLocated]
			addChartToWorkbook!(workbook,worksheet,c.chartDict,c.location);
		end
    =#
	#save (=write) Excel file and close it	
	writer.save()
	println(xlFile)
	return nothing
end

function writeDFtoExcel(excelData::ExcelData,existingFile::T,row::Int,col::Int,write_header::Bool,write_index::Bool) where {T <: AbstractString}
#http://search.cpan.org/~jmcnamara/Excel-Writer-XLSX/lib/Excel/Writer/XLSX.pm
	@assert min(row,col)>=0
    writer=pyModPandas.ExcelWriter(existingFile, engine = "xlsxwriter")
    
	for xlSheet in excelData.sheets
		df=xlSheet.data
	    sheet=xlSheet.name
		#create python dataframe	
		    dataDict = create_custom_dict(df)
		pyDF=PyCall.pycall(pyModPandas.DataFrame, PyCall.PyObject, dataDict,columns=names(df))		
		PyCall.pycall(pyDF."to_excel",PyCall.PyAny,writer, header=write_header,index=write_index, sheet_name = sheet,startrow=row, startcol=col, encoding="utf-8")  #index=false suppress the rowcount		
	end
	return writer
end

end # module



using DataFrames
d1=DataFrame(rand(4,4))
d2=DataFrame(rand(4,40))

using Main.ExcelWriter
sh1=ExcelSheet("a",d1)
sh2=ExcelSheet("ab",d2)
xlData=ExcelData()
push!(xlData.sheets,sh1)
push!(xlData.sheets,sh2)
writeToExcel(xlData,"C:\\temp\\tmp.xlsx",false,false)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants