Related
I have a file that is extracted from a system in a format over which I have no control. It is CSV (UTF-8) and there is a column that contains carriage returns (I'm not sure exactly what they are, but they were originally uploaded from an Excel file with information in the same column but with CTRL+ENTER to change line in the column).
Excel interprets them and changes line, so it creates a new line that does not fit with the headers and is not handled properly when the file is saved as a .csv file again. The text is within text delimiters ", so I'm guessing there should be a way to specify the handling of the text inside this delimiter.
I know there's probably no easy way to do that, but is there some VBA code I could use to handle this?
Here is an exemple of what it looks like when it is saved as a csv :
HEADER, GoalLibraryEntry, GUID, PARENT_GUID, LOCALE name, etc.
ADD, GoalLibraryEntry, 710103, 710100, en_US, "Test:,,,,,,,
a) Test1,,,,,,,,,,,
b) Test2,,,,,,,,,,,
c) Blabla,,,,,,,,,,,
d) Blablabla,,,,,,,,,,
e) Test5",,,,,,,,,,,
My problem is very similar to this one : Generating CSV file for Excel, how to have a newline inside a value
However, I've tried saving in ANSI before opening it in Excel without success. I also tried to add UTF-8 BOM at the start, but Excel does not seem to interpret it in any way.
What you're most likely seeing is multiline cells made when the user does a alt-enter on the keyboard.
The function you're looking for is clean (eg.) which you could use in VBA.
=clean(a1)
This removes non-printable characters from a cell.
The first few lines of my CSV file look like this (when viewed from Notepad++):
Trace,Original Serial Number,New Serial number
0000073800000000097612345678901234567890,0054,0001
When I open this file in excel, I get this:
For some reason, excel is truncating the serial numbers and the trace number. I have tried changing the format to Text but that still doesn't work, as excel only sees the value up to the 6:
7.38000000000976E+34
If I change it to Number:
73800000000097600000000000000000000.00
What can I do? I only have 60 lines, so if I have to start over and some how recopy the text into excel I will, but I'm afraid saving it will change the format once again.
You shouldn't need to start over or alter the existing CSV. The fastest way might be to use Excel's text import wizard. In the data tab under Get External Data click From Text and select your CSV file.
The wizard that appears will let you tell Excel the data type of each "column" and you can tell it to use text for your barcode.
Excel is trying to "help" you by formatting the input values. To avoid this, do not double-click the file to open it. Instead, open the Data tab and in the Get External Data section, click on From Text
Then tell the Import Wizard that the fields are Text:
One solution that may work for you depending on the environment you consume the csv, you can add a nonnumeric character to the beginning and end (e.g. a "_") of the values. This will force Excel to recognize it as text. You can then remove the "_"s in your downstream environment (SQL, Databricks, etc.) or even keep them if they don't interfere with your reporting.
In many EU countries a comma ',' is used as the decimal separator, whereas in the US a dot '.' is used.
CSV (Comma Separated Values) files are supposed to use the comma to separate cell values. However, often a tab '\t' or other characters are used instead.
What's interesting, Excel if you save a .csv file using Microsoft Excel in a EU country using the comma as a decimal separator, the value it uses to separate cell values is not an escaped comma, but a semicolon ';'. Looking on the net it seems that, if you are in the US, Excel will save .csv files using a proper comma (I can't verify this).
I'm trying to find a way to create a csv file that can be recognized by Excel without any user action, both in the EU and the US.
Here's an example using Excel with an Italian locale
The above, saved as .csv (MS-DOS), translates to
foo;foo bar;
foo'bar;"foo""bar";
foo,bar;foo.bar;
foo:bar;"foo;bar";
foo/bar;foo\bar;
"foo
bar";foo|bar;
foo;bar;foobar
this is to make the empty line appear
It may be possible that, depending on the local "list separator", this may not be recognized correctly.
I've read that the new Excel 2013 needs sep=; to be set as the first line in order to work correctly. This is an ugly hack, but it seems to also be working for Excel 2010 (except it gets overwritten on save)...
Does the above text work for you, if you save it as a csv?
Is there a less hacky way to tell Excel which character is the cell separator, without having the user to set things up?
Thanks.
Time to head back to a time before visual anything, and grab a command from the past. It will involve you manually writing the file out with VBA, but it has the criteria you expect: Write
Open "c:\tmp\myfile.csv" for output as #1
for i=1 to 100
write #1,range("A"&i),range("B"&i),range("C"&i)
next i
close #1
You will have to do a little manual work - it doesn't translate a single quote into a double quote, but the rest is as desired:
the Write # statement inserts commas between items and quotation marks around strings as they are written to the file
Numeric data is always written using the period as the decimal separator.
Dates are written as #yyyy-mm-dd hh:mm:ss#
I'm working on a feature to export search results to a CSV file to be opened in Excel. One of the fields is a free-text field, which may contain line breaks, commas, quotations, etc. In order to counteract this, I have wrapped the field in double quotes (").
However, when I import the data into Excel 2007, set the appropriate delimiter, and set the text qualifier to double quote, the line breaks are still creating new records at the line breaks, where I would expect to see the entire text field in a single cell.
I've also tried replacing CR/LF (\r\n) with just CR (\r), and again with just LF (\n), but no luck.
Has anyone else encountered this behavior, and if so, how did you fix it?
TIA,
-J
EDIT:
Here's a quick file I wrote by hand to duplicate the problem.
ID,Name,Description
"12345","Smith, Joe","Hey.
My name is Joe."
When I import this into Excel 2007, I end up with a header row, and two records. Note that the comma in "Smith, Joe" is being handled properly. It's just the line breaks that are causing problems.
Excel (at least in Office 2007 on XP) can behave differently depending on whether a CSV file is imported by opening it from the File->Open menu or by double-clicking on the file in Explorer.
I have a CSV file that is in UTF-8 encoding and contains newlines in some cells. If I open this file from Excel's File->Open menu, the "import CSV" wizard pops up and the file cannot be correctly imported: the newlines start a new row even when quoted. If I open this file by double-clicking on it in an Explorer window, then it opens correctly without the intervention of the wizard.
None of the suggested solutions worked for me.
What actually works (with any encoding):
Copy/paste the data from the csv-file (open in a text editor), then perform "text to columns" --> data gets transformed incorrectly.
The next stap is to go to the nearest empty column or empty worksheet and copy/paste again (same thing what you already have in your clipboard) --> automagically works now.
If you are doing this manually, download LibreOffice and use LibreOffice Calc to import your CSV. It does a much better job of stuff like this than any version of Excel I've tried, and it can save to XLS or XLSX as required if you need to transfer to Excel afterwards.
But if you're stuck with Excel and need a better fix, there seems to be a way. It seems to be locale dependent (which seems idiotic, in my humble opinion). I don't have Excel 2007, but I have Excel 2010, and the example given:
ID,Name,Description
"12345","Smith, Joe","Hey.
My name is Joe."
doesn't work. I wrote it in Notepad and chose Save as..., and next to the Save button you can choose the encoding. I chose UTF-8 as suggested, but with no luck. Changing the commas to semicolons worked for me, though. I didn't change anything else, and it just worked. So I changed the example to look like this, and chose the UTF-8 encoding when saving in Notepad:
ID;Name;Description
"12345";"Smith, Joe";"Hey.
My name is Joe."
But there's a catch! The only way it works is if you double-click the CSV file to open it in Excel. If I try to import data from text and chose this CSV, then it still fails on quoted newlines.
But there's another catch! The working field separator (comma in the original example, semicolon in my case) seems to depend on the system's Regional Settings (set under Control Panel -> Region and Language). In Norway, comma is the decimal separator. Excel seems to avoid this character and prefer a semicolon instead. I have access to another computer set to UK English locale, and on that computer, the first example with a comma separator works fine (only on doubleclick), and the one with semicolon actually fails! So much for interoperability. If you want to publish this CSV online and users may have Excel, I guess you have to publish both versions and suggest that people check which file gives the correct number of rows.
So all the details that I've been able to gather to get this to work are:
The file must be saved as UTF-8 with a BOM, which is what Notepad does when you chose UTF-8. I tried UTF-8 without BOM (can be switched easily in Notepad++), but then double-clicking the document fails.
You must use a comma or a semicolon separator, but not the one that is the decimal separator in your Regional Settings. Perhaps other characters work, but I don't know which.
You must quote fields that contain a newline with the " character.
I've used Windows line-endings (\r\n) both in the text field and as a record separator, that works.
You must double-click the file to open it, importing data from text doesn't work.
Hope this helps someone.
I have finally found the problem!
It turns out that we were writing the file using Unicode encoding, rather than ASCII or UTF-8. Changing the encoding on the FileStream seems to solve the problem.
Thanks everyone for all your suggestions!
Use Google Sheets and import the CSV file.
Then you can export that to use in Excel
Short Answer
Remove the newline/linefeed characters (\n with Notepad++). Excel will still recognise the carriage return character (\r) to separate records.
Long Answer
As mentioned newline characters are supported inside CSV fields but Excel doesn't always handle them gracefully. I faced a similar issue with a third party CSV that possibly had encoding issues but didn't improve with encoding changes.
What worked for me was removing all newline characters (\n). This has the effect of collapsing fields to a single record assuming that your records are separated by the combination of a carriage return and a newline (CR/LF). Excel will then properly import the file and recognise new records by the carriage return.
Obviously a cleaner solution is to first replace the real newlines (\r\n) with a temporary character combination, replacing the newlines (\n) with your seperating character of choice (e.g. comma in a semicolon file) and then replacing the temporary characters with proper newlines again.
If the field contains a leading space, Excel ignores the double quote as a text qualifier. The solution is to eliminate leading spaces between the comma (field separator) and double-quote. For example:
Broken:
Name,Title,Description
"John", "Mr.", "My detailed description"
Working:
Name,Title,Description
"John","Mr.","My detailed description"
If anyone stumbling across this thread and is looking for a definitive answer here goes (credit to the person mentioning LibreOffice:
1) Install LibreOffice
2) Open Calc and import file
3) My txt file had the fields separated by , and character fields enclosed in "
4) save as ODS file
5) Open ODS file in Excel
6) Save as .xls(x)
7) Done.
8) This worked perfectly for me and saved me BIGTIME!
+1 on J Ashley's comment. I ran into this problem also. It turns out that Excel requires:
A newline character("\n") in the quoted string
A carriage return and newline between each row.
E.g.
"Test", "Multiline item\n
multiline item"\r\n
"Test2", "Multiline item\n
multiline item"\r\n
I used notepad ++ to delimit each row properly and to only use newlines in the string. Discovered this by creating multiline entries in a blank excel doc and opening the csv in notepad ++.
Overview
Almost 10 years after the original post, Excel hasn't improved in importing CSV files. However, I found that it is much better in importing HTML tables. So, one can use Python to convert CSV to HTML and then import the resulting HTML to Excel.
The advantages of this approach are: (a) it works reliably, (b) you don't need to send your data to a third party service (e.g. Google sheets), (c) no extra "fat" installations required (LibreOffice, Numbers etc.) for most users, (d) higher level than meddling with CR/LF characters and BOM markers, (e) no need to fiddle with locale settings.
Steps
The following steps can be run on any bash-like shell as long as Python 3 is installed. Although Python can be used to directly read CSV, csvkit is used to do an intermediate conversion to JSON. This allows us to avoid having to deal with CSV intricacies in our Python code.
First, save the following script as json2html.py. The script reads a JSON file from stdin and dumps it as an HTML table:
#!/usr/bin/env python3
import sys, json, html
if __name__ == '__main__':
header_emitted = False
make_th = lambda s: "<th>%s</th>" % (html.escape(s if s else ""))
make_td = lambda s: "<td>%s</td>" % (html.escape(s if s else ""))
make_tr = lambda l, make_cell: "<tr>%s</tr>" % ( "".join([make_cell(v) for v in l]) )
print("<html><body>\n<table>")
for line in json.load(sys.stdin):
lk, lv = zip(*line.items())
if not header_emitted:
print(make_tr(lk, make_th))
header_emitted = True
print(make_tr(lv, make_td))
print("</table\n</body></html>")
Then, install csvkit in a virtual environment and use csvjson to feed the input file to our script. It is a good idea to disable cell type guessing with the -I argument:
$ virtualenv -p python3 pyenv
$ . ./pyenv/bin/activate
$ pip install csvkit
$ csvjson -I input.csv | python3 json2html.py > output.html
Now output.html can be imported in Excel. Line breaks in cells will have been preserved.
Optionally, you may want to cleanup your Python virtual environment:
$ deactivate
$ rm -rf pyenv
Multiline CSV can be imported easily in Excel versions with Power Query using following steps (tested in Excel 365 version 2207):
Go to Data-tab
Click "From Text/CSV" on the ribbon
Select file and click Import
Click "Transform Data" to open Power Query Editor
Click "Data source settings" on the Power Query Editor ribbon
Click "Change Source"
Select "Ignore quoted line breaks" from the "Line breaks" dropdown.
Click OK -> Close -> Close & Load
Paste into Notepad++, select Encoding > Encode in ANSI, copy all again and paste into Excel :)
I had a similar problem. I had some twitter data in MySQL. The data had Line feed( LF or \n) with in the data. I had a requirement of exporting the MySQL data into excel. The LF was messing up my import of csv file. So I did the following -
1. From MySQL exported to CSV with Record separator as CRLF
2. Opened the data in notepad++
3. Replaced CRLF (\r\n) with some string I am not expecting in the Data. I used ###~###! as replacement of CRLF
4. Replaced LF (\n) with Space
5. Replaced ###~###! with \r\n, so my record separator are back.
6. Saved and then imported into Excel
NOTE- While replacing CRLF or LF dont forget to Check Excended (\n,\r,\t... Checkbox [look at the left hand bottom of the Dialog Box)
My experience with Excel 2010 on WinXP with French regional settings
the separator of your imported csv must correspond to the list separator of your regional settings (; in my case)
you must double click on the file from the explorer. don't open it from Excel
On MacOS try using Numbers
If you have access to Mac OS I have found that the Apple spreadsheet Numbers does a good job of unpicking a complex multi-line CSV file that Excel could not handle. Just open the .csv with Numbers and then export to Excel.
Excel is incredibly broken when dealing with CSVs. LibreOffice does a much better job. So, I found out that:
The file must be encoded in UTF-8 with BOM, so consider this for all the points below
The best result, by far, is achieved by opening it from File Explorer
If you open it from within Excel there are two possible outcomes:
If it has only ASCII characters, it will most likely work
If it has non-ASCII characters, it will mess your line breaks
It seems to be heavily dependent on the decimal separator configured in the
OS's regional settings, so you have to select the right one
I would bet that it may also behave differently depending on OS and
Office version
This is for Excel 2016:
Just had the same problem with line breaks inside a csv file with the Excel Wizard.
Afterwards I was trying it with the "New Query" Feature:
Data -> New Query -> From File -> From CSV -> Choose the File -> Import -> Load
It was working perfectly and a very quick workaround for all of you that have the same problem.
With Excel 2019 I had a similar problem when working with CSV files via Data -> Import from text file / CSV. Once the connection is made and the data is synced, it reported xx error(s) because of shifted columns caused by the line breaks.
I managed to solve this by
Edit the query (Query -> Edit)
This opens the Power Query Editor
Go to Start -> Advanced Editor
This opens the query in text format, where line #2 had an instruction like
Source = Csv.Document(File.Contents("my.csv"),[Delimiter=",", .... , QuoteStyle=QuoteStyle.None]),
Change QuoteStyle.None to QuoteStyle.Csv
Click Finish
Apply & close
Documentation found here: https://learn.microsoft.com/en-us/powerquery-m/csv-document
NB. I since found where this is "hidden" in the UI. In the Power Query-editor, click Data source settings, Change source (bottom left), and the Line breaks combo should say Ignore line breaks between quotes.
NB2. Working from Dutch Excel here so my above-mentioned translations of button captions etc. may be a little off.
What just worked for me, importing into Excel directly provided that the import is done as a text format instead as csv format.
M/
just create a new sheet with cells with linebreak, save it to csv then open it with an editor that can show the end of line characters (like notepad++). By doing that you will notice that a linebreak in a cell is coded with LF while a "real" end of line is code with CR LF. VoilĂ , now you know how to generate a "correct" csv file for excel.
I also had this problem: ie., csv files (comma delimited, double quote delimited strings) with LF in quoted strings. These were downloaded Square files. I did a data import but instead of importing as text files, imported as "from HTML". This time it ignored the LF's in the quoted strings.
This worked on Mac, using csv and opening the file in Excel.
Using python to write the csv file.
data= '"first line of cell a1\r 2nd line in cell a1\r 3rd line in cell a1","cell b1","1st line in cell c1\r 2nd line in cell c1"\n"first line in cell a2"\n'
file.write(data)
In my case opening CSV in notepad++ and adding SEP="," as the first line allows me open CSV with line breaks and utf-8 in Excel without issues
Replace the separator with TAB(\t) instead of comma(,).
Then open the file in your editor (Notepad etc.), copy the content from there, then paste it in the Excel file.
It appears that this is much easier in more recent versions of Excel:
Go to "Data" -> "Get Data (Power Query)"
In the dialogue that opens, select "Text / CSV" on the right
Search for the file and then click "Next" and follow the recommendations (in my case, Excel now correctly realized it's UTF8 and that cells were separated by ";" and the text identifier were double quotes (")
You're done!
This took a little moment to load but afterwards I had an auto-formatted table that looked really nice and that did understand that multi-line entries were still part of the same entry.
If you want the multi-lines to show correctly, simply format the cells and under "Alignment", click the checkbox for "Wrap text". That should solve the last of your issues.
Good luck! ;-)
I want to generate a CSV file for user to use Excel to open it.
If I want to escape the comma in values, I can write it as "640,480".
If I want to keep the leading zeros, I can use ="001234".
But if I want to keep both comma and leading zeros in the value, writing as ="001,002" will be splitted as two columns. It seems no solution to express the correct data.
Is there any way to express 001, 002 in CSV for Excel?
Kent Fredric's answer contains the solution:
"=""001,002"""
(I'm bothering to post this as a separate answer because it's not clear from Kent's answer that it is a valid Excel solution.)
Put a prefix String on your data:
"N001,002","N002,003"
( As long as that prefix is not an E )
That notation ( In OpenOffice at least) above parses as a total of 2 columns with the N001,002 bytes correctly stored.
CSV Specification says that , is permitted inside quote strings.
Also, A warning from experience: make sure you do this with phone numbers too. Excel will otherwise interpret phone numbers as a floating point number and save them in scientific notation :/ , and 1.800E10 is not a really good phone number.
In OpenOffice, this RawCSV chunk also decodes as expected:
"=""001,002""","=""002,004"""
ie:
$rawdata = '001,002';
$equation = "=\"$rawdata\"";
$escaped = str_replace('"','""',$equation);
$csv_chunk = "\"$escaped\"" ;
Do
"""001,002"""
I found this out by typing "001,002" and then doing save-as CSV in Excel. If this isn't exactly what you want (you don't want quotes), this might be a good way for you to find what you want.
Another option might be use tab-delimited text, if this is an option for you.
A reader of my blog found a solution, ="001" & CHAR(44) & "002", it seems workable on my machine!
Pretty old thread but why don't you just add whitespace after your value. It will be then treated as string and no leading zeros will be stripped.
"001,002"." "
Since no-one mentioned it already, figured it was worth mentioning it in this old post.
If you add a horizontal tab character \t before the number, then MS Excel will also show the leading zero's. And the tab character doesn't show in the excel sheet. Even if it's surrounded by double-quotes. (F.e. \"\t001,002\")
It also looks nicer in Notepad++, compared to putting a \0 aka NULL before such number.
Looking more at the Excel spreadsheet it looks what you want can't be done using CSV.
This site http://office.microsoft.com/en-us/excel/HP052002731033.aspx says "If cells display formulas instead of formula values, the formulas are converted as text. All formatting, graphics, objects, and other worksheet contents are lost. The euro symbol will be converted to a question mark."
However, you can change how you load it to get the result you want. See this web page:
Microsoft import a text file.
The key thing is to choose Import External Data-Import Data-Text Files, go Next, Next, and then tick "Text" under column data format. This will prevent it being interpreted as a number, and losing formatting.
I was fiddling around with CSV to Excel (i use PHP to create the CSV, but i guess this solution works for any language. When you spot that a leading characters (such as + , - or 0 are disappearing, create the CSV with chr(13) as a prefix. This is a non printable character and it works wonders for my Excel Office 2010 version. I tried other non printable characters, but with no luck.
so i use Chirp Internet solution but tweaked with my prefix:
if (preg_match("/^0/", $str) || preg_match("/^\+?\d{8,}$/", $str) || preg_match("/^\d{4}.\d{1,2}.\d{1,2}/", $str)) {
$str = chr(13)."$str";
}
If you are using "Content-Disposition" and exporting from asp to excel using HTML tags,then you have to add "style='mso-number-format:\#;'" to that tag and making it to accept only Text values ,thereby leading zeroes omission will be avoided,If Forward slash"\" is accepted use double forward slash "\"
All the suggested answers don't seem to work for me right now ("=""blahblah""" and others) in all current Excel versions or Numbers app on OS X.
The only solution I found to be working by fiddling around is to add an escaped null character at the beginning of the string (which is \0 in PHP or C based languages). Everything ends up treated as is without being calculated or processed by the software when opening the calc sheet.
echo "\0" . $data;
Excel uses a default formatting for CSV columns depending on the content. So if you have 001 in a csv, excel will automatically turn it to 1.
The only way to keep the leading zeros in excel from a csv file is by changing the extension of the csv file to .txt, then just open excel, click on open, select the txt file, and you'll see the Text Import Wizard. Select your csv format (separated by commas), then just make sure you select "Text" as the format.
And that's it, now you can export that previous csv data to any other while keeping the leading zeros.
This is straightforward using Excel's Power Query functionality that allows you to perform step-by-step transformations.
Original File:
Add a Custom Column: