docs: def cli(ctx,
          amount,
          index,
          stage,
          stepresult,
          formattype,
          select,
          where,
          order,
          outputfile,
          showkeys,
          showvalues,
          showalways,
          position):
      """Export from memory to format supported by tablib"""
      if not ctx.bubble:
          msg = 'There is no bubble present, will not export'
          ctx.say_yellow(msg)
          raise click.Abort()
      path = ctx.home + '/'
  
      if stage not in STAGES:
          ctx.say_yellow('There is no known stage:' + stage)
          raise click.Abort()
      if stepresult not in exportables:
          ctx.say_yellow('stepresult not one of: ' + ', '.join(exportables))
          raise click.Abort()
  
      data_gen = bubble_lod_load(ctx, stepresult, stage)
  
      ctx.gbc.say('data_gen:', stuff=data_gen, verbosity=20)
  
      part = get_gen_slice(ctx.gbc, data_gen, amount, index)
      ctx.gbc.say('selected part:', stuff=part, verbosity=20)
  
      aliases = get_pairs(ctx.gbc, select, missing_colon=True)
      if position or len(aliases) == 0:
          ctx.gbc.say('adding position to selection of columns:',
                      stuff=aliases, verbosity=20)
          aliases.insert(0, {'key': buts('index'), 'val': 'BUBBLE_IDX'})
          ctx.gbc.say('added position to selection of columns:',
                      stuff=aliases, verbosity=20)
  
      wheres = get_pairs(ctx.gbc, where)
      # TODO: use aliases as lookup for wheres
  
      data = tablib.Dataset()
  
      data.headers = [sel['val'] for sel in aliases]
      ctx.gbc.say('select wheres:' + str(wheres), verbosity=20)
      ctx.gbc.say('select aliases:' + str(aliases), verbosity=20)
      ctx.gbc.say('select data.headers:' + str(data.headers), verbosity=20)
  
      not_shown = True
      try:
          for ditem in part:
              row = []
              ctx.gbc.say('curr dict', stuff=ditem, verbosity=101)
  
              flitem = flat(ctx, ditem)
              ctx.gbc.say('curr flat dict', stuff=flitem, verbosity=101)
              row_ok = True
              for wp in wheres:
                  # TODO: negative selects: k:None, k:False,k:Zero,k:Null,k:0,k:-1,k:'',k:"",
                  # TODO: negative selects:
                  # k:BUBBLE_NO_KEY,k:BUBBLE_NO_VAL,k:BUBBLE_NO_KEY_OR_NO_VAL
  
                  wcheck_key=True
                  if wp['key'] not in flitem:
                      row_ok = False
                      wcheck_key=False
                  if wcheck_key and wp['val'] not in str(flitem[wp['key']]):
                      row_ok = False
              if not row_ok:
                  continue
  
              for sel in aliases:
                  if sel['key'] in flitem:
                      row.append(flitem[sel['key']])
                  else:
                      # temporary to check, not use case for buts()
                      bnp = '____BTS_NO_PATH_'
                      tempv = get_flat_path(ctx, flitem, sel['key'] + '.*', bnp)
                      if tempv != bnp:
                          row.append(tempv)
                      else:
                          row.append('None')
                          # TODO maybe 'NONE', or just '' or something like:
                          # magic.export_format_none
  
              data.append(row)
              # todo: count keys, and show all keys in selection: i,a
              if not_shown and showkeys:
                  if not showalways:
                      not_shown = False
                  ks = list(flitem.keys())
                  ks.sort()
                  ctx.say(
                      'available dict path keys from first selected dict:', verbosity=0)
                  for k in ks:
                      ctx.say('keypath: ' + k, verbosity=0)
                      if showvalues:
                          ctx.say('value: ' + str(flitem[k]) + '\n', verbosity=0)
  
      except Exception as excpt:
          ctx.say_red('Cannot export data', stuff=excpt)
          raise click.Abort()
  
      if not outputfile:
          outputfile = path + 'export/export_' + \
              stepresult + '_' + stage + '.' + formattype
  
      # todo: order key must be present in selection
      # add to selection before
      # and remove from result before output to format.
      if order:
          olast2 = order[-2:]
          ctx.gbc.say('order:' + order + ' last2:' + olast2, verbosity=100)
          if olast2 not in [':+', ':-']:
              data = data.sort(order, False)
          else:
              if olast2 == ':+':
                  data = data.sort(order[:-2], False)
              if olast2 == ':-':
                  data = data.sort(order[:-2], True)
  
      # Write `spreadsheet` to disk
      formatted = None
      if formattype == 'yaml':
          formatted = data.yaml
      if formattype == 'json':
          formatted = data.json
      if formattype == 'csv':
          formatted = data.csv
  
      # TODO:
      # if formattype == 'ldif':
      #    formatted = data.ldif
  
      if formattype == 'tab':
          # standard, output, whatever tablib makes of it, ascii table
          print(data)
  
      if formatted:
          enc_formatted = formatted.encode('utf-8')
          of_path = opath.Path(outputfile)
          of_dir = of_path.dirname()
          if not of_dir.exists():
              of_dir.makedirs_p()
  
          with open(outputfile, 'wb') as f:
              f.write(enc_formatted)
              ctx.say_green('exported: ' + outputfile)