diff --git a/KiBOM/csv_writer.py b/KiBOM/csv_writer.py index 1f7928f6..d294be41 100644 --- a/KiBOM/csv_writer.py +++ b/KiBOM/csv_writer.py @@ -36,10 +36,11 @@ def WriteCSV(filename, groups, net, headings, prefs): writer = csv.writer(f, delimiter=delimiter, lineterminator="\n") - if prefs.numberRows: - writer.writerow(["Component"] + headings) - else: - writer.writerow(headings) + if not prefs.hideHeaders: + if prefs.numberRows: + writer.writerow(["Component"] + headings) + else: + writer.writerow(headings) count = 0 rowCount = 1 @@ -63,19 +64,20 @@ def WriteCSV(filename, groups, net, headings, prefs): rowCount += 1 - #blank rows - for i in range(5): - writer.writerow([]) - - writer.writerow(["Component Groups:",nGroups]) - writer.writerow(["Component Count:",nTotal]) - writer.writerow(["Fitted Components:", nFitted]) - writer.writerow(["Number of PCBs:",prefs.boards]) - writer.writerow(["Total components:", nBuild]) - writer.writerow(["Schematic Version:",net.getVersion()]) - writer.writerow(["Schematic Date:",net.getSheetDate()]) - writer.writerow(["BoM Date:",net.getDate()]) - writer.writerow(["Schematic Source:",net.getSource()]) - writer.writerow(["KiCad Version:",net.getTool()]) + if not prefs.hideHeaders: + #blank rows + for i in range(5): + writer.writerow([]) + + writer.writerow(["Component Groups:",nGroups]) + writer.writerow(["Component Count:",nTotal]) + writer.writerow(["Fitted Components:", nFitted]) + writer.writerow(["Number of PCBs:",prefs.boards]) + writer.writerow(["Total components:", nBuild]) + writer.writerow(["Schematic Version:",net.getVersion()]) + writer.writerow(["Schematic Date:",net.getSheetDate()]) + writer.writerow(["BoM Date:",net.getDate()]) + writer.writerow(["Schematic Source:",net.getSource()]) + writer.writerow(["KiCad Version:",net.getTool()]) return True \ No newline at end of file diff --git a/KiBOM/html_writer.py b/KiBOM/html_writer.py index d6d83472..ef20f822 100644 --- a/KiBOM/html_writer.py +++ b/KiBOM/html_writer.py @@ -6,6 +6,7 @@ import os BG_GEN = "#E6FFEE" BG_KICAD = "#FFE6B3" BG_USER = "#E6F9FF" +BG_EMPTY = "#FF8080" #return a background color for a given column title def bgColor(col): @@ -58,24 +59,26 @@ def WriteHTML(filename, groups, net, headings, prefs): #PCB info - html.write("
| Source File | {source} |
| BoM Date | {date} |
| Schematic Version | {version} |
| Schematic Date | {date} |
| KiCad Version | {version} |
| Component Groups | {n} |
| Component Count (per PCB) | {n} |
| Fitted Components (per PCB) | {n} |
| Number of PCBs | {n} |
| Total Component Count (for {n} PCBs) | {t} |
Kicad Fields (default)
\n'.format(bg=BG_KICAD)) - html.write('Generated Fields
\n'.format(bg=BG_GEN)) - html.write('User Fields
\n'.format(bg=BG_USER)) + if not prefs.hideHeaders: + html.write("| Source File | {source} |
| BoM Date | {date} |
| Schematic Version | {version} |
| Schematic Date | {date} |
| KiCad Version | {version} |
| Component Groups | {n} |
| Component Count (per PCB) | {n} |
| Fitted Components (per PCB) | {n} |
| Number of PCBs | {n} |
| Total Component Count (for {n} PCBs) | {t} |
Kicad Fields (default)
\n'.format(bg=BG_KICAD)) + html.write('Generated Fields
\n'.format(bg=BG_GEN)) + html.write('User Fields
\n'.format(bg=BG_USER)) + html.write('Empty Fields
\n'.format(bg=BG_EMPTY)) #component groups html.write('| {n} | \n'.format(n=rowCount)) for n, r in enumerate(row): - bg = bgColor(headings[n]) + + if len(r) == 0: + bg = BG_EMPTY + else: + bg = bgColor(headings[n]) html.write('\t{val} | \n'.format(bg=' bgcolor={c}'.format(c=bg) if bg else '', val=link(r))) diff --git a/KiBOM/preferences.py b/KiBOM/preferences.py index 70e5acac..c79a6dc6 100644 --- a/KiBOM/preferences.py +++ b/KiBOM/preferences.py @@ -49,6 +49,7 @@ class BomPref: self.useRegex = True #Test various columns with regex self.compareFootprints = True #test footprints when comparing components self.boards = 1 + self.hideHeaders = False self.verbose = False #by default, is not verbose self.configurations = [] #list of various configurations diff --git a/KiBOM_CLI.py b/KiBOM_CLI.py index 50d9d90a..e4a3169e 100644 --- a/KiBOM_CLI.py +++ b/KiBOM_CLI.py @@ -31,9 +31,10 @@ def say(*arg): parser = argparse.ArgumentParser(description="KiBOM Bill of Materials generator script") parser.add_argument("netlist", help='xml netlist file. Use "%%I" when running from within KiCad') -parser.add_argument("--output", "-o", help='BoM output file name.\nUse "%%O" when running from within KiCad to use the default output name (csv file).\nFor e.g. HTML output, use "%%O.html"\r\nIf output file is unspecified, default output filename (csv format) will be used', default=None) -parser.add_argument("--boards", "-b", help="Number of boards to build (default = 1)", type=int, default=1) +parser.add_argument("output", default="", help='BoM output file name.\nUse "%%O" when running from within KiCad to use the default output name (csv file).\nFor e.g. HTML output, use "%%O.html"') +parser.add_argument("-b", "--boards", help="Number of boards to build (default = 1)", type=int, default=1) parser.add_argument("-v", "--verbose", help="Enable verbose output", action='count') +parser.add_argument("-n", "--noheader", help="Do not generate file headers; data only.", action='count') parser.add_argument("--cfg", help="BoM config file (script will try to use 'bom.ini' if not specified here)") args = parser.parse_args() @@ -48,25 +49,6 @@ verbose = args.verbose is not None input_file = os.path.abspath(input_file) say("Input:",input_file) - -output_file = args.output - -if output_file is None: - output_file = input_file.replace(".xml","_bom.csv") - -#enfore a proper extension -valid = False -extensions = [".xml",".csv",".txt",".tsv",".html"] -for e in extensions: - if output_file.endswith(e): - valid = True - break -if not valid: - close("Extension must be one of",extensions) - -output_file = os.path.abspath(output_file) - -say("Output:",output_file) #look for a config file! #bom.ini by default @@ -83,6 +65,8 @@ pref = BomPref() #pass various command-line options through pref.verbose = verbose pref.boards = args.boards +if args.noheader: + pref.hideHeaders = True if os.path.exists(config_file): pref.Read(config_file) @@ -115,14 +99,42 @@ for g in groups: for f in g.fields: columns.AddColumn(f) +#don't add 'boards' column if only one board is specified if pref.boards <= 1: columns.RemoveColumn(ColumnList.COL_GRP_BUILD_QUANTITY) say("Removing:",ColumnList.COL_GRP_BUILD_QUANTITY) + +#todo +write_to_bom = True +result = True #Finally, write the BoM out to file -result = WriteBoM(output_file, groups, net, columns.columns, pref) +if write_to_bom: + + output_file = args.output + + if output_file is None: + output_file = input_file.replace(".xml","_bom.csv") + + #enfore a proper extension + valid = False + extensions = [".xml",".csv",".txt",".tsv",".html"] + for e in extensions: + if output_file.endswith(e): + valid = True + break + if not valid: + close("Extension must be one of",extensions) + + output_file = os.path.abspath(output_file) + + say("Output:",output_file) + + result = WriteBoM(output_file, groups, net, columns.columns, pref) if result: sys.exit(0) else: sys.exit(-1) + +