The format specifiers of -printf in GNU find takes width and alignment (etc.) qualifiers, just as the printf() C function, meaning you can align the data left or right and, crucially for your current project, allocate a certain width for the data.
Default output:
$ find . -printf '%M %u %g %p\n' drwxr-xr-x kk wheel . -rw-r--r-- kk wheel ./.zshrc -rw-r--r-- kk wheel ./file drwxr-xr-x root wheel ./rootstuff -rw-r--r-- root wheel ./rootstuff/SECRET -rw------- kk wheel ./.viminfo
Specifying widths (6) for user and group columns (right-justified):
$ find . -printf '%M %6u %6g %p\n' drwxr-xr-x kk wheel . -rw-r--r-- kk wheel ./.zshrc -rw-r--r-- kk wheel ./file drwxr-xr-x root wheel ./rootstuff -rw-r--r-- root wheel ./rootstuff/SECRET -rw------- kk wheel ./.viminfo
Same, but left-justified:
$ find . -printf '%M %-6u %-6g %p\n' drwxr-xr-x kk wheel . -rw-r--r-- kk wheel ./.zshrc -rw-r--r-- kk wheel ./file drwxr-xr-x root wheel ./rootstuff -rw-r--r-- root wheel ./rootstuff/SECRET -rw------- kk wheel ./.viminfo
With file sizes in bytes, allocating 5 digits (zero-filled, because just showing how it could be done):
$ find . -printf '%M %-6u %-6g %05s %p\n' drwxr-xr-x kk wheel 00512 . -rw-r--r-- kk wheel 00000 ./.zshrc -rw-r--r-- kk wheel 00095 ./file drwxr-xr-x root wheel 00512 ./rootstuff -rw-r--r-- root wheel 00000 ./rootstuff/SECRET -rw------- kk wheel 00922 ./.viminfo
Note that the ls command may well allocate widths for its columns dynamically based on the actual need whereas your find -printf command would have to use static widths, unless you run find twice to first compute the needed space for each column and then again to actually format the output (this is why the find -ls output is so wide, it does not use a two-pass approach and instead just gives each column ample space in the hope that everything will align somewhat nicely).
Of course, if you don't have many thousands of files, and you just want a listing of everything, recursively (i.e., you don't need to filter or do something else with the found pathnames in find), you could just use ls:
$ ls -d -l **/* -rw------- 1 kk wheel 922 Jul 25 23:46 .viminfo -rw-r--r-- 1 kk wheel 0 Jul 19 23:39 .zshrc -rw-r--r-- 1 kk wheel 95 Jul 25 23:51 file drwxr-xr-x 2 root wheel 512 Jul 26 00:00 rootstuff -rw-r--r-- 1 root wheel 0 Jul 26 00:00 rootstuff/SECRET
This relies on the ** globbing pattern being available, which it is by default in the zsh shell, and in bash if you use shopt -s globstar. It also relies on the shell matching hidden names. The zsh shell will do this if you set the GLOB_DOTS option with setopt GLOB_DOTS, and bash does it with shopt -s dotglob.
This would not work if your globbing pattern expands to a list so long that it generates an "Argument list too long" error.
This output would be different from the ordinary ls -l -R output in that directories would not be listed individually with breaks between them.
column -tbut if there are spaces in the filenames, the result will be wrong