Emacs: import a CSV into org-mode

EmacsCsvImportOrg Mode

Emacs Problem Overview


Emacs has a very nice extension by the name of org-mode.

I would like to be able to easily load CSV files into org-mode without significant grief. All I've been able to find is table-import or table-capture, which, simply put, don't work even approximately well.

Note that part of my issue is text strings with a comma within them. 1,2,3,4 is different than 1,2,"3,4".

Is there a function out there or a perl script that one could run to transform a csv file into org-mode format?

Thanks!

Emacs Solutions


Solution 1 - Emacs

From the org-mode manual:

> C-c | Convert the active region to > table. If every line contains at least > one TAB character, the function > assumes that the material is tab > separated. If every line contains a > comma, comma-separated values (CSV) > are assumed. If not, lines are split > at whitespace into fields. You can use > a prefix argument to force a specific > separator: C-u forces CSV, C-u C-u > forces TAB, and a numeric argument N > indicates that at least N consecutive > spaces, or alternatively a TAB will be > the separator. If there is no active > region, this command creates an empty > Org table.

So just paste the data into an org file, select it, and do C-u C-c | .

Solution 2 - Emacs

I'm assuming you want to convert your CSV specifically into org-mode tables. If that's not the case, you may want to be more explicit about output format in your question.

Something like this should do it, or at least get you a starting point you can hack on:

  #!/usr/bin/perl
  
  use strict;
  use warnings;
  
  use Text::CSV;
  
  my $csv = Text::CSV->new();
  
  while ( my $line = <DATA> ) {
    if ( $csv->parse( $line )) {
      my $str = join '|' , $csv->fields();
      print "|$str|\n";
    }
  }
  
  
  __DATA__
  1,2,3,4
  1,2,"3,4"

Solution 3 - Emacs

Have a look at:

C-h f org-table-convert-region

I'm always converting csv so I added this to my .emacs.

(defun org-convert-csv-table (beg end)
  (interactive (list (mark) (point)))
  (org-table-convert-region beg end ",")
  )

(add-hook 'org-mode-hook
      (lambda ()
    (define-key org-mode-map (kbd "<f6>") 'org-convert-csv-table)))

update

Here is another function that considers the quoted commas as well :

 a,"12,12",b --> a | 12,12 |b

feel free to improve it :-).

(defun org-convert-csv-table (beg end)
  ; convert csv to org-table considering "12,12"
  (interactive (list (point) (mark)))
  (replace-regexp "\\(^\\)\\|\\(\".*?\"\\)\\|," (quote (replace-eval-replacement
						    replace-quote (cond ((equal "^" (match-string 1)) "|")
											       ((equal "," (match-string 0)) "|")
											       ((match-string 2))) ))  nil  beg end)

Solution 4 - Emacs

Try this:

;; Insert a file and convert it to an org table
(defun aleblanc/insert-file-as-org-table (filename)
  "Insert a file into the current buffer at point, and convert it to an org table."
  (interactive (list (ido-read-file-name "csv file: ")))
  (let* ((start (point))
	(end (+ start (nth 1 (insert-file-contents filename)))))
    (org-table-convert-region start end)
    ))

Solution 5 - Emacs

Here is a bit of a hack-job, but it works.

when you export the CSV file, force quotes around each entry, then replace all "," as a vertical bar.

Finally, I make a macro that does something like this:

C-a    ; Beginning-of-line
|      ; Self-insert-char
C-e    ; end-of-line
|      ; Self-insert-char
<down> ; Down one line

(I am not 100% sure if | is a self-insert-char or not, so its best to record your own macro)

Hit tab somewhere in the middle of the table, and org-mode formats it properly. I find this easier to do in a narrowed region.

Caveat: If you have a vertical bar in your input.. it probably won't work quite right. Situations like that should be easy to spot, and relatively easy to fix.

Generally, when importing something text-like into org-mode, I have found a combination of some smart macro writing, and search-replace to be the easiest way

I hope that helps.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaul NathanView Question on Stackoverflow
Solution 1 - EmacsDon WomickView Answer on Stackoverflow
Solution 2 - EmacsgenehackView Answer on Stackoverflow
Solution 3 - EmacsDJJView Answer on Stackoverflow
Solution 4 - EmacsAleblancView Answer on Stackoverflow
Solution 5 - EmacsJonathan ArkellView Answer on Stackoverflow