You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.3 KiB

  1. #
  2. # Example python script to generate a BOM from a KiCad generic netlist
  3. # The KiCad generic xml netlist is expected to be encoded UTF-8
  4. #
  5. # Example: Sorted and Grouped HTML BOM
  6. #
  7. """
  8. @package
  9. Output: HTML
  10. Grouped By: Value, DNP
  11. Sorted By: Ref
  12. Fields: Ref, Qnty, Value, Part, Datasheet, Description, Vendor, DNP
  13. Command line:
  14. python "pathToFile/bom_html_grouped_by_value.py" "%I" "%O.html"
  15. """
  16. from __future__ import print_function
  17. # Import the KiCad python helper module and the csv formatter
  18. import kicad_netlist_reader
  19. import kicad_utils
  20. import sys
  21. # Start with a basic html template
  22. html = """
  23. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  24. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  25. <html xmlns="http://www.w3.org/1999/xhtml">
  26. <head>
  27. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  28. </head>
  29. <body>
  30. <h1><!--SOURCE--></h1>
  31. <p><!--DATE--></p>
  32. <p><!--TOOL--></p>
  33. <p><!--COMPCOUNT--></p>
  34. <table>
  35. <!--TABLEROW-->
  36. </table>
  37. </body>
  38. </html>
  39. """
  40. # Generate an instance of a generic netlist, and load the netlist tree from
  41. # the command line option. If the file doesn't exist, execution will stop
  42. net = kicad_netlist_reader.netlist(sys.argv[1])
  43. # Open a file to write to, if the file cannot be opened output to stdout
  44. # instead
  45. canOpenFile = True
  46. try:
  47. f = kicad_utils.open_file_write(sys.argv[2], 'wb')
  48. except IOError:
  49. e = "Can't open output file for writing: " + sys.argv[2]
  50. print(__file__, ":", e, file=sys.stderr)
  51. f = sys.stdout
  52. canOpenFile = False
  53. components = net.getInterestingComponents( excludeBOM=True )
  54. # Output a set of rows for a header providing general information
  55. html = html.replace('<!--SOURCE-->', net.getSource())
  56. html = html.replace('<!--DATE-->', net.getDate())
  57. html = html.replace('<!--TOOL-->', net.getTool())
  58. html = html.replace('<!--COMPCOUNT-->', "<b>Component Count:</b>" + \
  59. str(len(components)))
  60. row =""
  61. row += "<tr><th>Ref</th>"
  62. row += "<th>Qnty</th>"
  63. row += "<th>Value</th>" + "<th>Part</th>" + "<th>Datasheet</th>"
  64. row += "<th>Description</th>" + "<th>Vendor</th>" + "<th>DNP</th></tr>"
  65. html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
  66. # Get all of the components in groups of matching parts + values
  67. # (see kicad_netlist_reader.py)
  68. grouped = net.groupComponents(components)
  69. # Output all of the component information
  70. for group in grouped:
  71. refs = ""
  72. # Add the reference of every component in the group and keep a reference
  73. # to the component so that the other data can be filled in once per group
  74. for component in group:
  75. if len(refs) > 0:
  76. refs += ", "
  77. refs += component.getRef()
  78. c = component
  79. row = "<tr><td>" + refs +"</td><td>" + str(len(group))
  80. row += "</td><td>" + c.getValue()
  81. row += "</td><td>" + c.getLibName() + ":" + c.getPartName()
  82. row += "</td><td>" + c.getDatasheet()
  83. row += "</td><td>" + c.getDescription()
  84. row += "</td><td>" + c.getField("Vendor")
  85. row += "</td><td>" + c.getDNPString() + "</td></tr>"
  86. row += "\n"
  87. html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
  88. # Write the formatted html to the file
  89. if sys.version_info[0] < 3:
  90. f.write(html)
  91. else:
  92. f.write(html.encode('utf-8'))
  93. f.close()
  94. if not canOpenFile:
  95. sys.exit(1)