public static <T extends Record> String toAsciiTable(final Collection<T> collection,
                                                         final boolean qualifiedFields) {
        final TableBuilder<T> builder = AsciiTable.builder(collection);
        if (collection.isEmpty()) {
            return "NO DATA";
        } else {
            // Grab any record to figure out what fields we have
            final T aRecord = collection.stream()
                    .findAny()
                    .orElseThrow();

            for (int i = 0; i < aRecord.fields().length; i++) {
                final Field<?> field = aRecord.field(i);
                final int iCopy = i;
                final String fieldName = qualifiedFields
                        ? field.getName()
                        : field.getQualifiedName().toString();

                final Function<T, String> getter;

                if (field.getName().endsWith("_ms")) {
                    getter = rec -> {
                        final Object val = rec.get(iCopy);
                        if (val == null) {
                            return null;
                        } else if (val instanceof Long) {
                            return Instant.ofEpochMilli((Long) val).toString();
                        } else {
                            return val.toString();
                        }
                    };
                } else {
                    getter = rec -> NullSafe.get(rec.get(iCopy), Object::toString);
                }
                builder.withColumn(Column.of(fieldName, getter));
            }
        }
        return builder.build();
    }
Dumps the collection of records to an ASCII table or "NO DATA" if the collection is empty/null
stroom-db-util/src/main/java/stroom/db/util/JooqUtil.java