You can use an HTML table.
E.g. I use this code to line up the 'Y's under the corresponding guild rank numbers:
	Code:
	                string Body;
                Body += "<br>Ranks: ";
                char Temp[100];
                for(int i = 1; i <= GUILD_MAX_RANK; ++i)
                {
                        sprintf(Temp, "%i = %s", i, guild_mgr.GetRankName(c->GuildID(), i));
                        Body += Temp;
                        if(i != GUILD_MAX_RANK)
                                Body += ", ";
                }
                Body += "<br><br><TABLE>";
                Body += "<TR><TD> <TD>1<TD>2<TD>3<TD>4<TD>5<TD>6<TD>7<TD>8<TD>";
                for(int i = 1; i <= GUILD_PERMISSION_MAX; ++i)
                {
                        sprintf(Temp, "%2i. ", i);
                        Body += "<TR><TD>";
                        Body += Temp;
                        Body += guild_mgr.GetPermissionName(i);
                        Body += "<TD>";
                        for(int j = 1; j <= GUILD_MAX_RANK; ++j)
                        {
                                if(guild_mgr.CheckPermission(c->GuildID(), j, i))
                                        Body += "Y";
                                Body += "<TD>";
                        }
                }
                Body += "</table><br>The following characters have the old Guild Banker flag:<br>";
                c->SendWindow(1,2, 0, "OK", "OK", 0, 2, c, "Title", Body.c_str());
 