docs: def get_string(self, **kwargs):
          """Return string representation of table in current state.
  
          Arguments:
  
          title - optional table title
          start - index of first data row to include in output
          end - index of last data row to include in output PLUS ONE (list slice style)
          fields - names of fields (columns) to include
          header - print a header showing field names (True or False)
          border - print a border around the table (True or False)
          hrules - controls printing of horizontal rules after rows.  Allowed values: ALL, FRAME, HEADER, NONE
          vrules - controls printing of vertical rules between columns.  Allowed values: FRAME, ALL, NONE
          int_format - controls formatting of integer data
          float_format - controls formatting of floating point data
          padding_width - number of spaces on either side of column data (only used if left and right paddings are None)
          left_padding_width - number of spaces on left hand side of column data
          right_padding_width - number of spaces on right hand side of column data
          vertical_char - single character string used to draw vertical lines
          horizontal_char - single character string used to draw horizontal lines
          junction_char - single character string used to draw line junctions
          sortby - name of field to sort rows by
          sort_key - sorting key function, applied to data points before sorting
          reversesort - True or False to sort in descending or ascending order
          print empty - if True, stringify just the header for an empty table, if False return an empty string """
  
          options = self._get_options(kwargs)
  
          lines = []
  
          # Don't think too hard about an empty table
          # Is this the desired behaviour?  Maybe we should still print the
          # header?
          if self.rowcount == 0 and (not options["print_empty"] or not options["border"]):
              return ""
  
          # Get the rows we need to print, taking into account slicing, sorting,
          # etc.
          rows = self._get_rows(options)
  
          # Turn all data in all rows into Unicode, formatted as desired
          formatted_rows = self._format_rows(rows, options)
  
          # Compute column widths
          self._compute_widths(formatted_rows, options)
          self._hrule = self._stringify_hrule(options)
  
          # Add title
          title = options["title"] or self._title
          if title:
              lines.append(self._stringify_title(title, options))
  
          # Add header or top of border
          if options["header"]:
              lines.append(self._stringify_header(options))
          elif options["border"] and options["hrules"] in (ALL, FRAME):
              lines.append(self._hrule)
  
          # Add rows
          for row in formatted_rows:
              lines.append(self._stringify_row(row, options))
  
          # Add bottom of border
          if options["border"] and options["hrules"] == FRAME:
              lines.append(self._hrule)
  
          return self._unicode("\n").join(lines)