Package: ezspreadsheet
EZ SpreadsheetA simple API to store/load python objects to/from spreadsheetsTable of contentsGoalsFeaturesObject SerializationObject DeserializationFlexibilityReadabilityInstallationQuick-startAdditional DocumentationGoalsThis project has a few goals:Make OO projects easier to serializeMake interfacing with spreadsheet files simpleUse as minimal syntax as possible to complete the aboveFeaturesBelow are a some of the features in ezspreadsheet.Object serializationThe api lets you directly serialize object instances into spreadsheets:fromezspreadsheetimportSpreadsheetclassAnimal():def__init__(self,name:str,conservation_status:str):self.name=nameself.conservation_status=conservation_statusleopard_gecko=Animal('Leopard Gecko','Least Concern')withSpreadsheet('animals.xlsx',Animal)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(leopard_gecko)Object deserializationThe api lets you deserialize objects from spreadsheets back into instances (Note if you don't provide a class to build back into a dynamicnamedtupleis generated):fromezspreadsheetimportSpreadsheetclassAnimal():def__init__(self,name:str,conservation_status:str):self.name=nameself.conservation_status=conservation_statusleopard_gecko=Animal('Leopard Gecko','Least Concern')philippine_eagle=Animal('Philippine Eagle','Threatened')# Store DatawithSpreadsheet('animals.xlsx',Animal)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(leopard_gecko,philippine_eagle)# Retrieve data using the same class construtorwithSpreadsheet('animals.xlsx',Animal)asinput_sheet:# to use .csv just change file extensionanimals,instances=input_sheet.load("animals")print(instances)# prints: [<__main__.Animal object at 0x0000011BAB89A3A0>, <__main__.Animal object at 0x0000011BAD4289A0>]# Note the class constructor is the sameprint(Animal==animals)# Prints: True# Retrieve namedtuple classes when no class constructor is availablewithSpreadsheet('animals.xlsx')asinput_sheet:# to use .csv just change file extensionanimals,instances=input_sheet.load("animals")print(animals)# Prints: <class 'ezspreadsheet.animals'>print(instances)# Prints: [animals(name='Leopard Gecko', conservation_status='Least Concern'), animals(name='Philippine Eagle', conservation_status='Threatened')]# Note the class constructor is now differentprint(Animal==animals)# Prints: FalseFlexibilityThere is syntactic flexibility to allow an arbitrary number of instance arguments, or simple Iterables (like lists and tuples):fromezspreadsheetimportSpreadsheetclassAnimal():def__init__(self,name:str,conservation_status:str):self.name=nameself.conservation_status=conservation_statusleopard_gecko=Animal('Leopard Gecko','Least Concern')philippine_eagle=Animal('Philippine Eagle','Threatened')# Direct instanceswithSpreadsheet('animals.xlsx',Animal)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(leopard_gecko,philippine_eagle)# Iterablesinstances=[]instances.append(leopard_gecko)instances.append(philippine_eagle)withSpreadsheet('animals.xlsx',Animal)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(instances)ReadabilityYou can specify areadablevariable in theSpreadsheet.store()method to allow Iterable instance attributes to be written in a readable format (note they will be deserialized as strings):fromezspreadsheetimportSpreadsheetfromdataclassesimportdataclass@dataclassclassUser():Name:strAge:intWeight:intFamily:list# Note that Iterables will be flattened to a string with newline seperatorsjd=User("John Doe",20,75,["Abby","Mike","Janice"])# Store Data as readablewithSpreadsheet('users.xlsx',User)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(jd,readable=True)# Retrieve namedtuple classes when no class constructor is availablewithSpreadsheet('users.xlsx')asinput_sheet:# to use .csv just change file extensionusers,instances=input_sheet.load("users")print(instances[0].Family)# Prints: - Abby\n- Mike\n- Janice# Store Data as not readablewithSpreadsheet('users.xlsx',User)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(jd)# Retrieve namedtuple classes when no class constructor is availablewithSpreadsheet('users.xlsx')asinput_sheet:# to use .csv just change file extensionusers,instances=input_sheet.load("users")print(instances[0].Family)# Prints: ['Abby', 'Mike', 'Janice']InstallationFrom PyPiRunpip install ezspreadsheetorsudo pip3 install ezspreadsheetFrom sourceClone this repo: (https://github.com/Descent098/ezspreadsheet)Runpip install .orsudo pip3 install .in the root directoryQuick-startNote that syntax does not change between.xlsxand.csvfiles, you can replace.xlsxwith.csvand below examples will workStore some animal instances in a spreadsheet called 'animals.xlsx', then read back the datafromezspreadsheetimportSpreadsheetclassAnimal():def__init__(self,name:str,conservation_status:str):self.name=nameself.conservation_status=conservation_statusleopard_gecko=Animal('Leopard Gecko','Least Concern')philippine_eagle=Animal('Philippine Eagle','Threatened')# StorewithSpreadsheet('animals.xlsx',Animal)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(leopard_gecko,philippine_eagle)# LoadwithSpreadsheet('animals.xlsx',Animal)asinput_sheet:# to use .csv just change file extension_,instances=output_sheet.load("animals")print(instances)# prints: [<__main__.Animal object at 0x0000011BAB89A3A0>, <__main__.Animal object at 0x0000011BAD4289A0>]Store a list of instances into a spreadsheet called 'users.xlsx'fromezspreadsheetimportSpreadsheetimportrandomimportstringfromdataclassesimportdataclass@dataclassclassUser():Name:strAge:intWeight:intFamily:list# Note that Iterables will be flattened to a string with newline seperatorsinstances=[]ranstring=lambda:''.join(random.choices(string.ascii_uppercase,k=10))# Generates a random 10 character stringforiinrange(1000):instances.append(User(ranstring(),random.randint(12,100),random.randint(75,400),[ranstring(),ranstring(),ranstring()]))withSpreadsheet('users.xlsx',User)asoutput_sheet:# to use .csv just change file extensionoutput_sheet.store(instances)Differences between xlsx and csvPlease note there are some differnces between.xlsxfiles and.csvfiles:.xlsxfiles are significantly faster because they isntantiate cell objects and are C-level optimized instead of just doing plain text generation. If you need to save thousands of objects, I would recommend using.xlsxfiles.When passingreadable=TruetoSpreadsheet.store()the formatting for.xlsxfiles allows for newlines, so iterables are broken by newlines\n. CSV readers use newlines to read csv files (even when told not to), so they are broken by tabs\tin.csvfiles instead.Additional DocumentationAdditional documentation can be found athttps://kieranwood.ca/ezspreadsheetFor details on how contributing to the project, please seeCONTRIBUTING.md, for details on upcoming changes seeour roadmap.For most recent changes seeCHANGELOG.md.Changelog0.2.2; November 24th 2020Updated links to include docs and source code urls0.2.1; November 24th 2020Updated description to match name change0.2.0; November 24th 2020Added deserialization methods for xlsx filesAdded serialization and deserialization methods for CSV filesChanged name from ezexcel to ezspreadsheetSplit Xlxs processing to internal class and converted Spreadsheet class to dispatching class0.1.1; September 25th 2020Fixed logo loading on PyPiBug fixesFixed loading issue with logo on PyPi0.1.0; September 25thInitial release of EZ ExcelFeaturesAbility to provide a class to instantiate a SpreadsheetAbility to pass instances in an iterable of class to Spreadsheet to be serializedAutomatically flatten Iterable attributes within instances to endline delimited stringsAdded testing suite for all existing functionalityDocumentation improvementsWrote all existing documentation :)