11

I have a spreadsheet which really has only one complicated table. I basically convert the spreadsheet to a cvs and use a groovy script to generate the INSERT scripts.

However, I cannot do this with a table that has 28 fields with data within some of the fields on the spreadsheet that make importing into the CVS even more complicated. So the fields in the new CVS are not differentiated properly or my script has not accounted for it.

Does anyone have any suggestions on a better approach to do this? Thanks.

Kulwant
  • 641
  • 2
  • 11
  • 28
  • This appears to be very similiar to [3621798](http://stackoverflow.com/questions/3621798) – arober11 Dec 02 '12 at 23:09
  • possible duplicate of [How to IMPORT a excel file in to MYSQL DATABASE](http://stackoverflow.com/questions/1310166/how-to-import-a-excel-file-in-to-mysql-database) – Josh Lee Jun 13 '13 at 20:19
  • Does this answer your question? [How to import an excel file in to a MySQL database](https://stackoverflow.com/questions/1310166/how-to-import-an-excel-file-in-to-a-mysql-database) – tripleee Oct 19 '21 at 18:03

4 Answers4

6

Have a look at LOAD DATA INFILE statement. It will help you to import data from the CSV file into table.

Devart
  • 119,203
  • 23
  • 166
  • 186
3

This is a recurrent question on stackoverflow. Here is an updated answer.

There are actually several ways to import an excel file in to a MySQL database with varying degrees of complexity and success.

  1. Excel2MySQL or Navicat utilities. Full disclosure, I am the author of Excel2MySQL. These 2 utilities aren't free, but they are the easiest option and have the fewest limitations. They also include additional features to help with importing Excel data into MySQL. For example, Excel2MySQL automatically creates your table and automatically optimizes field data types like dates, times, floats, etc. If your in a hurry or can't get the other options to work with your data then these utilities may suit your needs.

    screenshot of Excel2MySQL

  2. LOAD DATA INFILE: This popular option is perhaps the most technical and requires some understanding of MySQL command execution. You must manually create your table before loading and use appropriately sized VARCHAR field types. Therefore, your field data types are not optimized. LOAD DATA INFILE has trouble importing large files that exceed 'max_allowed_packet' size. Special attention is required to avoid problems importing special characters and foreign unicode characters. Here is a recent example I used to import a csv file named test.csv.

    enter image description here

  3. phpMyAdmin: Select your database first, then select the Import tab. phpMyAdmin will automatically create your table and size your VARCHAR fields, but it won't optimize the field types. phpMyAdmin has trouble importing large files that exceed 'max_allowed_packet' size.

    enter image description here

  4. MySQL for Excel: This is a free Excel Add-in from Oracle. This option is a bit tedious because it uses a wizard and the import is slow and buggy with large files, but this may be a good option for small files with VARCHAR data. Fields are not optimized.

    enter image description here

panofish
  • 7,578
  • 13
  • 55
  • 96
  • Can Excel2Mysql handle a csv file directly? My csv is way too big to convert to Excel. – ccleve Feb 16 '16 at 17:35
  • 1
    @panofish Your Excel2MySql was the only solution that worked for me. Had an error with Navicat, had error with Access, tried EVERYTHING. But your software worked flawlessly, just didn't mention until I ran the import for a long time that the trial leaves some rows blank. Wish I knew that in advance, lol. – notacouch May 01 '20 at 20:34
  • 1
    @notacouch Thanks for the feedback. Perhaps, I will add a notification about the blank records before licensing to avoid the confusion for others. Excel2MySQL is very solid and reliable. – panofish May 02 '20 at 21:35
  • 1
    @panofish You're welcome. Yep, I did wind up purchasing a license the same day and it saved me ..... tons of time, effort, headache, worked flawlessly. Thank you! – notacouch May 07 '20 at 23:50
1

For comma-separated values (CSV) files, the results view panel in Workbench has an "Import records from external file" option that imports CSV data directly into the result set. Execute that and click "Apply" to commit the changes.

For Excel files, consider using the official MySQL for Excel plugin.

Philip Olson
  • 4,662
  • 1
  • 24
  • 20
0

A while back I answered a very similar question on the EE site, and offered the following block of Perl, as a quick and dirty example of how you could directly load an Excel sheet into MySQL. Bypassing the need to export / import via CSV and so hopefully preserving more of those special characters, and eliminating the need to worry about escaping the content.

#!/usr/bin/perl -w
# Purpose: Insert each Worksheet, in an Excel Workbook, into an existing MySQL DB, of the same name as the Excel(.xls).
#          The worksheet names are mapped to the table names, and the column names to column names.
#          Assumes each sheet is named and that the first ROW on each sheet contains the column(field) names.
#

use strict;
use Spreadsheet::ParseExcel;
use DBI;
use Tie::IxHash;

die "You must provide a filename to $0 to be parsed as an Excel file" unless @ARGV;

my $sDbName              = $ARGV[0];
   $sDbName              =~ s/\.xls//i;
my $oExcel               = new Spreadsheet::ParseExcel;
my $oBook                = $oExcel->Parse($ARGV[0]);
my $dbh                  = DBI->connect("DBI:mysql:database=$sDbName;host=192.168.123.123","root", "xxxxxx", {'RaiseError' => 1,AutoCommit => 1});
my ($sTableName, %hNewDoc, $sFieldName, $iR, $iC, $oWkS, $oWkC, $sSql);

print "FILE: ", $oBook->{File} , "\n";
print "DB: $sDbName\n";
print "Collection Count: ", $oBook->{SheetCount} , "\n";

for(my $iSheet=0; $iSheet < $oBook->{SheetCount} ; $iSheet++)
{
 $oWkS                   = $oBook->{Worksheet}[$iSheet];
 $sTableName             = $oWkS->{Name};
 print "Table(WorkSheet name):", $sTableName, "\n";
 for(my $iR   = $oWkS->{MinRow} ; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ;  $iR++)
 {
  tie ( %hNewDoc, "Tie::IxHash");
  for(my $iC = $oWkS->{MinCol} ; defined $oWkS->{MaxCol} && $iC <= $oWkS->{MaxCol} ; $iC++)
  {
   $sFieldName           = $oWkS->{Cells}[$oWkS->{MinRow}][$iC]->Value;
   $sFieldName           =~ s/[^A-Z0-9]//gi;  #Strip non alpha-numerics from the Column name
   $oWkC                 = $oWkS->{Cells}[$iR][$iC];
   $hNewDoc{$sFieldName} = $dbh->quote($oWkC->Value) if($oWkC && $sFieldName);
  }
  if ($iR == $oWkS->{MinRow}){
        #eval { $dbh->do("DROP TABLE $sTableName") };
        $sSql             = "CREATE TABLE IF NOT EXISTS $sTableName (".(join " VARCHAR(512), ", keys (%hNewDoc))." VARCHAR(255))";
        #print "$sSql \n\n";
        $dbh->do("$sSql");
  } else {
        $sSql = "INSERT INTO $sTableName (".(join ", ",keys (%hNewDoc)).") VALUES (".(join ", ",values (%hNewDoc)).")\n";
        #print "$sSql \n\n";
        eval { $dbh->do("$sSql") };
  }
 }
 print "Rows inserted(Rows):", ($oWkS->{MaxRow} - $oWkS->{MinRow}), "\n";
}
# Disconnect from the database.
$dbh->disconnect();

Note:

  1. Change the connection ($oConn) string to suit, and if needed add a user-id and password to the arguments.
  2. If you need XLSX support a quick switch to Spreadsheet::XLSX is all that's needed. Alternatively it only takes a few lines of code, to detect the filetype and call the appropriate library.
  3. The above is a simple hack, assumes everything in a cell is a string / scalar, if preserving type is important, a little function with a few regexp can be used in conjunction with a few if statements to ensure numbers / dates remain in the applicable format when written to the DB
  4. The above code is dependent on a number of CPAN modules, that you can install, assuming outbound ftp access is permitted, via a:

    cpan YAML Data::Dumper Spreadsheet::ParseExcel Tie::IxHash Encode Scalar::Util File::Basename DBD::mysql

Should return something along the following lines (tis rather slow, due to the auto commit):

# ./Excel2mysql.pl test.xls 
FILE: test.xls
DB: test
Collection Count: 1
Table(WorkSheet name):Sheet1
Rows inserted(Rows):9892
arober11
  • 1,969
  • 18
  • 31
  • Excel2mysql.pl perl source code should not be confused with the application Excel2MySQL. The application is much faster and easier, but it is not free. – panofish May 02 '20 at 21:39