Each set of games stores data in its own format; while there may be similarities, offsets can differ. You need to identify which format(s) you would like to support, and implement readers for each. Species can be read as an integer, then localized to whatever language based on a string list for that language. Nickname can be read from the data, depending on how the game encodes strings (gen6+ use UTF-16 with \0000 terminators).
There are quite a few open source implementations in various languages; here's a Python one for LGP/E which is the "Gen7b" format of PKM data.
https://github.com/Lincoln-LM/PyNXReader/blob/cb15cf5935fdcb8de9b8a9c268d87bc161d3af9a/structure/PK7b.py
You'll need to break down each of your "needs" into smaller and smaller needs.
Parsing the nickname? Need a reader, and need the offset to get the Species ID, then need a list of strings to localize the value to a display string.
Parsing the ball? Need a reader, and need the offset to get the Ball ID, then need a list of strings to localize the value to a display string.
See the pattern and reusable parts?
I would recommend opening a pk* file in a hex editor, so you can "feel" what you're actually telling the program to do. Files are just data, and understanding (without code) how that data is stored is essentially a prerequisite to understand what you need to reimplement your understanding as code.