← Back to team overview

kicad-developers team mailing list archive

New superior BOM generator: bom_csv_grouped_by_value.py


KiCad Users,

Standing on the shoulders of Brian, I was able to enhance the script

   * bom_csv_grouped_by_value.py *

This script is now the best BOM generator for KiCad that I am aware of, surpassing the
XSLT technology which held that position (in my view) only yesterday.

Here are some of the more pertinent lines of python in the script:

# subset the components to those wanted in the BOM, controlled
# by <configure> block in kicad_netlist_reader.py
components = net.getInterestingComponents()

compfields = net.gatherComponentFieldUnion(components)
partfields = net.gatherLibPartFieldUnion()

# remove Reference, Value, Datasheet, and Footprint, they will come from 'columns' below
partfields -= set( ['Reference', 'Value', 'Datasheet', 'Footprint'] )

columnset = compfields | partfields     # union

# prepend an initial 'hard coded' list and put the enchillada into list 'columns'
columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Datasheet'] +


To use it, simply add the following line to your BOM dialog:

python <kicad_install_dir>/scripts/bom_in_python/bom_csv_grouped_by_value.py "%I" "%O"

The output is a CSV file which can be loaded into a spreadsheet.

There are 4 blacklists supported, and these are documented at the top of


Feel free to edit that file.  Maybe someday someone can make that configuration logic into
a config file.  But for now you have to edit the script nested module, said above.

When grouping components, you only have one row for the group.  So the choice of text used
for each column can be a bit tricky.  Which text do you use, how do you know it pertains
to all components in the group?

This is how it works:

The first non-blank field encountered for any grouped component, is taken as valid for
that whole group.  So the only danger you have is making sure that any non-blank text is
consistent or valid for the whole group.  Only one component in a group needs non-blank
field text, any one.   And even that is not the case if you put that same field, with
valid text in your libpart instead.  The search precedence is:

*) find first non-blank field text, for each field in a group.
*) if empty, find it in the libpart.
*) if empty, use a blank for that row.

The script really is not that complicated, so don't be afraid of it.

Brian did a nice job putting the work into the kicad_netlist_reader.py, where it can be
re-used.  I extended that concept quite a bit with additional functionality, all
re-useable.  One important new function is getInterestingComponents(), which is the one
that consults the blacklists.

I expect and encourage improvements, and even forks of this work.  The idea was to
jettison BOM generation where it can be worked on by anyone with specific needs.  I will
likely keep of copy of this particular generator under a different name, so I can be
assured that it works at least as good as it does now in the future.  This acknowledges
the belief that BOMs are a bit personal, and requirements vary by user.



Follow ups