;;; ---------------------------------------------------------------------
;;;  CSVTABLE-bgol.lsp
;;;  Command:  XTBL
;;;
;;;  PURPOSE
;;;  A CAD-native equivalent of the "Excel to CAD" table-conversion
;;;  workflow: reads a CSV file (as exported from Excel) and builds a
;;;  native ACAD_TABLE entity directly in the drawing at a picked
;;;  insertion point -- header row styled distinctly from the data
;;;  rows, with user-controlled column width and row height -- so
;;;  spreadsheet data becomes a real, editable CAD table without any
;;;  separate conversion application.
;;;
;;;  USAGE
;;;    1. Load this file (APPLOAD or drag-drop onto the drawing window).
;;;    2. Type   XTBL   at the command line and press Enter.
;;;    3. Select the source CSV file (first row = header).
;;;    4. Pick the table insertion point.
;;;    5. Enter the column width and row height (or accept defaults).
;;;    6. A native TABLE entity is created on layer "BGOL-XTBL",
;;;       populated with the CSV's header + data rows.
;;;
;;;  NOTES
;;;    - Requires a CAD platform whose entmake supports ACAD_TABLE
;;;      (AutoCAD 2005+/BricsCAD/ZWCAD). Column count is taken from
;;;      the header row; ragged rows are padded/truncated to match.
;;;    - This is an original, independently written implementation.
;;;      It is INSPIRED by the general idea of Excel-to-CAD table
;;;      conversion utilities common in survey/civil drafting
;;;      workflows (typically distributed as standalone .exe
;;;      applications), but the code, command name and file name here
;;;      are new, entirely AutoLISP-native, and are NOT copied from,
;;;      nor identical to, any specific third-party product.
;;;
;;;  ---------------------------------------------------------------------
;;;  Developed and shared for the CAD community by:  BGol Community
;;;  Community website:                              https://bgol.in/
;;;  License:  Open-source & free to use, modify, and share for all.
;;;            Provided "as is", without warranty of any kind.
;;;  ---------------------------------------------------------------------

(vl-load-com)

(defun BGOL:XTBL-EnsureLayer (lname / )
  (if (not (tblsearch "LAYER" lname))
    (entmake (list '(0 . "LAYER")
                   '(100 . "AcDbSymbolTableRecord")
                   '(100 . "AcDbLayerTableRecord")
                   (cons 2 lname)
                   '(70 . 0)
                   '(62 . 5)          ; blue
                   '(6 . "Continuous")))
  )
)

(defun BGOL:XTBL-Split (str delim / pos out remain)
  (setq out '())
  (setq remain str)
  (while (setq pos (vl-string-search delim remain))
    (setq out (append out (list (substr remain 1 pos))))
    (setq remain (substr remain (+ pos 1 (strlen delim))))
  )
  (setq out (append out (list remain)))
  out
)

(defun C:XTBL ( / path f line rows fields ncols nrows ins colw rowh
                  doc space tblobj r c row val)
  (BGOL:XTBL-EnsureLayer "BGOL-XTBL")
  (setq path (getfiled "Select CSV File to Convert (header row first)" "" "csv" 0))
  (if path
    (progn
      (setq f (open path "r"))
      (setq rows '())
      (if f
        (progn
          (while (setq line (read-line f))
            (if (and line (> (strlen (vl-string-trim " \t" line)) 0))
              (setq rows (append rows (list (BGOL:XTBL-Split line ","))))
            )
          )
          (close f)
          (setq nrows (length rows))
          (if (> nrows 0)
            (progn
              (setq ncols (length (car rows)))
              (setq ins (getpoint "\nTable insertion point: "))
              (if ins
                (progn
                  (setq colw (getreal "\nColumn width <25.0>: "))
                  (if (not colw) (setq colw 25.0))
                  (setq rowh (getreal "\nRow height <8.0>: "))
                  (if (not rowh) (setq rowh 8.0))
                  (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
                  (setq space (if (= (getvar "CVPORT") 1)
                                 (vla-get-PaperSpace doc)
                                 (vla-get-ModelSpace doc)))
                  (setq tblobj (vla-AddTable space
                                              (vlax-3d-point ins)
                                              nrows ncols
                                              rowh colw))
                  (vla-put-Layer tblobj "BGOL-XTBL")
                  (vla-put-RegenerateTableSuppressed tblobj :vlax-true)
                  (setq r 0)
                  (foreach row rows
                    (setq c 0)
                    (while (< c ncols)
                      (setq val (if (< c (length row)) (nth c row) ""))
                      (vla-SetText tblobj r c val)
                      (setq c (1+ c))
                    )
                    (setq r (1+ r))
                  )
                  (vla-put-RegenerateTableSuppressed tblobj :vlax-false)
                  (princ (strcat "\nXTBL: CSV imported as a " (itoa nrows) "x" (itoa ncols)
                                 " table on layer BGOL-XTBL."))
                )
                (princ "\nNo insertion point picked.")
              )
            )
            (princ "\nNo rows found in the selected CSV file.")
          )
        )
        (princ "\nCould not open the selected file.")
      )
    )
    (princ "\nNo file selected.")
  )
  (princ)
)

(princ "\nCSVTABLE-bgol.lsp loaded. Type XTBL to import a CSV as a native CAD table.")
(princ "\n  -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --")
(princ)
