Pyrevit.output table formatting


I am adding multiple tables to the output window, and the formatting seems to be off. How can I get the ‘Instance Count’ columns lined up? See image for reference.

Anyone have any feedback as to why this formatting isn’t consistent?

Can you show the code and also the data you are feeding to the print_table with a print(data) statement?
It tools me a while to get the hang of the data structure that feeds the table. Usually fixed by either transposing the data or filing in the gaps in the dataset

Sure, the code is straight forward and in alignment with the examples that I was able to find:
output = script.get_output()
output.print_table(table_data = data,
title = tabletitle + " Category, Total Families Found: " + str(famCount) + " >>>",
columns = [“Family Name”, “Instance Count”],
formats = [‘’, ‘’])

I have also included another image of the output. I suspect that the width of the strings in the ‘Family Name’ column has something to do with where the ‘Instance Count’ column starts. Is there a way to “hard code” those column widths in order to maintain consistency?

Hello again, any thoughts?

thinking out loud about an easy fix:

  • adding a empty column between the fam name and the instance count columns
  • or reducing the output window width

Neither of the suggestions offered resolved or changed the output/display.

Here’s some sample code I used to look at this problem.

Basically, because pyrevit prints out all the text as html, we add “&nbsp” (non-breaking space) to the end of all text entries.
We add as many as we need to match the length of the longest string of all the tables. This ensures all the values have the same “length” including white space, so all the tables have the same formatting.
There may be a better way but I don’t want to spend that much time on it.
Hope this helps.

from pyrevit import script
from pyrevit.revit import DB, HOST_APP

doc = HOST_APP.doc

def format_value(value, max_length):
    value = str(value)
    return value + (" " * (max_length - len(value)))

def format_data(data, max_length):
    return [[format_value(value, max_length) for value in item] for item in data]

def get_families_by_category(category):
    category_id = DB.ElementId(category)
    return [fam for fam in DB.FilteredElementCollector(doc).OfClass(DB.Family) if fam.FamilyCategory.Id == category_id]

def get_instance_count(family):
    return len([element for element in DB.FilteredElementCollector(family.Document).OfClass(DB.FamilyInstance).WhereElementIsNotElementType() if element.Symbol.Family.Id == family.Id])

def get_data_by_category(category):
    families = get_families_by_category(category)
    data = {}
    for family in families:
        if len(family.Name) > MAX_STRING_LENGTH:
            MAX_STRING_LENGTH = len(family.Name)
        data[family.Name] = get_instance_count(family)
    return len(families), [[key, value] for key, value in data.items()]

plumb_fixture_family_count, plumb_fixture_data = get_data_by_category(DB.BuiltInCategory.OST_PlumbingFixtures)
mech_equipment_family_count, mech_equipment_data = get_data_by_category(DB.BuiltInCategory.OST_MechanicalEquipment)

column_headers = [format_value("Family Name", MAX_STRING_LENGTH), format_value("Instance Count", MAX_STRING_LENGTH)]

plumb_fixture_data = format_data(plumb_fixture_data, MAX_STRING_LENGTH)
mech_equipment_data = format_data(mech_equipment_data, MAX_STRING_LENGTH)

output = script.get_output()
output.print_table(table_data = plumb_fixture_data,
title = "PLUMBING FIXTURE Category, Total Families Found: {} >>>".format(plumb_fixture_family_count),
columns = column_headers)

output.print_table(table_data = mech_equipment_data,
title = "MECHANICAL EQUIPMENT Category, Total Families Found: {} >>>".format(mech_equipment_family_count),
columns = column_headers)