Reading and Writing Tabular Data
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Written against MATLAB R2026b. GNU Octave 11.3.0 has none of the functions this page is about (readtable, writetable, readmatrix, readcell, readtimetable and detectImportOptions all report "not found" in the Docker image used for this section), so the MATLAB examples are not run here: they were checked line by line against the R2026b documentation and show no captured output. The one exception is the last example, which uses base-language functions that Octave also has and was run in Octave 11.3.0. Output printed in the examples below that comes from the documentation is described in prose, not reproduced.
Most data that enters a MATLAB program starts as a file: a CSV exported by a logger, a spreadsheet kept by a colleague, a JSON document from a service. Since R2013b the idiom is to read such column-oriented data into a table, clean it there, and write a table back when the work is done. This page covers that idiom: the functions, their options, the import options objects that give finer control, spreadsheets and Google Sheets, and the interactive Import Tool. Reading lines and bytes by hand (fopen, fgetl, fread) is covered on Low-Level File I/O and the File System, and JSON and web services on JSON, XML and Web Access.
The function family
The format-specific functions share one naming scheme: read or write, then the container that holds the data in MATLAB. They determine the file format from the file extension (or from the FileType name-value argument when the extension does not say).
| Reader | Returns | Writer | Introduced |
|---|---|---|---|
|
a table: one variable per column, each with its own type |
|
R2013b |
|
a timetable: the first |
|
R2019a (reader) |
|
a numeric array, or another type chosen with |
|
R2019a |
|
a cell array: every element of the file in its own cell, whatever its type |
|
R2019a |
|
one workspace variable per column: |
none |
R2019a |
|
lines of text, a structure, a dictionary |
|
see the sibling pages |
The "Introduced" column gives the release of the reader, from the "Version History" of its reference page (detectImportOptions is R2016b); the release of each writer was not looked up. When the data is not column-oriented (a header block, free-form lines, a binary layout), the low-level functions or textscan are the tools.
Supported formats
The table below is a trimmed form of the table on the "Supported File Formats for Import and Export" page, keeping the rows relevant to tabular data. The full page also lists images, audio, video, scientific formats (CDF, FITS, HDF, HDF5, netCDF) and STL.
| File content | Extensions | Import functions | Export functions |
|---|---|---|---|
MAT-file (saved workspace) |
|
|
|
Delimited text, numbers only |
|
|
|
Delimited text, numbers or a mix of text and numbers |
|
|
|
Plain text lines |
any |
|
|
Spreadsheet |
|
|
|
Compressed and archived data |
|
|
see File Compression |
XML |
|
|
|
JSON |
|
|
|
Parquet |
|
|
|
Low-level files |
any |
|
|
Two rows of that table are not the whole story. readtable reads more than the table shows (JSON since R2026a, HTML and Microsoft Word documents since R2021b, as the sections below explain), and writetable writes JSON and XML as well as text and spreadsheets. The authoritative lists are on the reference pages of the functions.
The heatflow sensor log
The heatflow scenario (The heatflow scenario) logs thermocouple readings to data/sensors.csv. The listing is the illustrative sample used on Timetables; the real file is longer, and the logger leaves a field empty when a reading is lost:
Time,SensorID,Temperature
2026-01-15 10:00:00,S1,21.5
2026-01-15 10:00:30,S2,22.1
2026-01-15 10:01:00,S1,21.6
2026-01-15 10:01:30,S2,
2026-01-15 10:02:00,S1,21.8
2026-01-15 10:02:30,S2,22.4
The page uses this file for every example. The shortest way to read it is also the first thing to try:
T = readtable("data/sensors.csv");
head(T)
class(T.Time) % "datetime": the stamps were recognised
class(T.SensorID) % "cell" by default, see TextType below
class(T.Temperature) % "double"; the empty field is NaN
Not run here. readtable reads the first line as variable names (Time, SensorID, Temperature), detects that the first column holds dates and times and that the third holds numbers, and fills the empty field with NaN. The sections below take that default apart and show each step you can change.
Source: MATLAB documentation: readtable
readtable
T = readtable(filename) creates a table from a text, spreadsheet, JSON (R2026a), XML, HTML or Microsoft Word file. The four forms of the call:
| Syntax | Meaning |
|---|---|
|
Detects delimiter, header and variable types from the file. |
|
Changes some of the detection with name-value arguments, such as |
|
Uses an import options object created by |
|
Both. Alongside an options object only a few name-value arguments are still honoured: |
The file name can be a relative or absolute path, a file on the MATLAB path, an http:// or https:// URL, or a remote location (Amazon S3, Azure Blob Storage, HDFS). Since R2026b S3 and Azure locations can also be given as https:// URLs. A name without an extension needs FileType ("text", "delimitedtext", "fixedwidth", "spreadsheet", "json", "xml", "worddocument" or "html").
What the defaults do
For text files (.txt, .dat, .csv) the default is one table variable per column, variable names from the first row, empty numeric fields as NaN, empty text fields as empty text, and white space around fields ignored. Every line must have the same number of delimiters. For spreadsheets the default is again one variable per column and names from the first row. The documentation states that MATLAB’s detection becomes more accurate with more data; a six-row sample like the one above is the worst case, where one odd row can change what is detected.
Name-value arguments that matter
The reference page lists many arguments, grouped by purpose. These are the ones used day to day; those marked "options object" are also properties of the import options objects described below, where they are usually better set.
| Argument | Effect |
|---|---|
|
Number of lines to skip before the table starts (text and spreadsheet). |
|
The cells or lines to read. |
|
The worksheet, by name or by position (default 1). Spreadsheets only. |
|
|
|
Where the names are, when they are not on the first line. |
|
Read the first column (or the stated column) as row names instead of as a variable. |
|
|
|
|
|
|
|
The locale used to read month and day names, for example |
|
For files that write |
|
Text to read as a missing value, such as |
|
What to do with missing fields and with fields that cannot be converted: |
|
A line with more fields than variables: |
|
|
|
Text-parsing details. |
|
The character encoding of a text file, such as |
|
Helps the detection when the file is irregular. |
|
On Windows, whether to start Excel to read the spreadsheet. The default is |
% Not run here (MATLAB R2026b).
T = readtable("data/sensors.csv", ...
TextType="string", ...
TreatAsMissing=["NA" "-999"], ...
VariableNamingRule="preserve");
summary(T)
Not run here. T.SensorID is now a string array, NA and -999 fields in the temperature column become NaN, and the header names are kept exactly as written. The Name=Value form requires R2021a; before it, the arguments are pairs separated by commas with the name in quotes.
Source: MATLAB documentation: readtable
Gaps and bad fields
The two cleaning arguments act on the file, before any missing-data function sees the table. MissingRule="omitrow" drops every row that has a gap; "omitvar" drops every column that has one; "error" stops. ImportErrorRule does the same for fields that exist but cannot be converted (a date that is not a date). The documentation example reads a small outages file whose second and fourth rows have gaps and whose third row has an unreadable date: by default the gaps become NaN and NaT (not-a-time), and the unreadable date also becomes NaT. Setting ImportErrorRule="omitrow" and MissingRule="omitvar" together changes the result to the rows without bad dates and the columns without gaps. Choose the rule deliberately: "omit" silently shortens the data.
Import options: detectImportOptions and setvartype
When the name-value arguments are not enough, create an import options object. It is a configuration that describes how to read one kind of file; you can inspect it, change it, apply it to many files, and keep it as a file-reading recipe.
opts = detectImportOptions(filename) locates the table in a file and returns the matching object. The class depends on the file:
| File | Object returned |
|---|---|
Delimited text ( |
|
Fixed-width text |
|
Spreadsheet |
|
JSON (R2026a) |
|
XML |
|
Microsoft Word document |
|
HTML |
|
detectImportOptions accepts the same table-level name-value arguments as readtable (Delimiter, NumHeaderLines, Sheet, VariableNamingRule, MissingRule, ImportErrorRule, DecimalSeparator, and many more), so they customise the detection itself. The object is then edited at two levels.
Table level: assign properties of opts. The most useful are VariableNames, VariableTypes, SelectedVariableNames (which variables to import), DataLines (for text, for example [2 Inf]), VariableNamesLine, Delimiter, MissingRule, ImportErrorRule and VariableNamingRule; for spreadsheets DataRange and VariableNamesRange replace the line properties. preview(filename,opts) shows the first rows of the result without reading everything.
Variable level: use three functions, which take variable names (or positions) and return a modified copy of the object.
| Function | Purpose |
|---|---|
|
Changes the data type of the selected variables, for example to |
|
Sets per-variable options: |
|
Returns the |
% Not run here (MATLAB R2026b).
opts = detectImportOptions("data/sensors.csv");
disp([opts.VariableNames' opts.VariableTypes']) % what was detected
opts = setvartype(opts, "SensorID", "categorical");
opts = setvartype(opts, "Temperature", "single");
opts = setvaropts(opts, "Time", InputFormat="yyyy-MM-dd HH:mm:ss", ...
TimeZone="UTC");
opts = setvaropts(opts, "Temperature", TreatAsMissing="-999");
opts.SelectedVariableNames = ["Time" "SensorID" "Temperature"];
T = readtable("data/sensors.csv", opts);
Not run here. The detected types are typically datetime, char and double; after the edits Time is a zoned datetime, SensorID is a categorical array, Temperature is single with -999 read as missing, and the same opts can read every other file in the folder that has this layout. The InputFormat is the one used on Dates and Times; a format that does not match makes the import produce NaT unless ImportErrorRule says otherwise. The object stores types as the names MATLAB reports in opts.VariableTypes (double, char, string, categorical, datetime, logical, …).
Source: MATLAB documentation: setvartype
Reusing options across files
A logger produces a file per day. Build the options once from a representative file, adjust, and read them all:
% Not run here (MATLAB R2026b).
opts = detectImportOptions("data/sensors.csv");
opts = setvartype(opts, "SensorID", "categorical");
files = dir("data/sensors-*.csv");
dailyTables = cell(numel(files), 1);
for k = 1:numel(files)
dailyTables{k} = readtable(fullfile(files(k).folder, files(k).name), opts);
end
sensorLog = vertcat(dailyTables{:});
Not run here. vertcat concatenates tables that have the same variable names and compatible types, and a shared opts guarantees both. Reading many similar files is also the job of a datastore (see Large Data, Datastores and Tall Arrays).
Options without an input file
detectImportOptions needs a file to inspect. When the format is known, create the object directly and skip the detection: delimitedTextImportOptions, fixedWidthImportOptions, xmlImportOptions, htmlImportOptions and wordDocumentImportOptions each take name-value arguments for the table-level settings. The documentation example builds one for a six-column file:
% Not run here (MATLAB R2026b).
opts = delimitedTextImportOptions(NumVariables=6, ...
Delimiter="|", ImportErrorRule="omitrow");
opts.MissingRule = "omitrow";
opts.DataLines = 2;
opts.VariableNamesLine = 1;
opts.VariableNamingRule = "preserve";
opts = setvartype(opts, 1:6, ...
["string" "datetime" "single" "single" "datetime" "categorical"]);
opts = setvaropts(opts, 3:4, DecimalSeparator=",");
Not run here. Source: MATLAB documentation: Control How MATLAB Imports Your Data
This is the right tool for a file whose first rows confuse detection (a comment block, a unit row) or when the same recipe must read files that have no data in them yet.
readtimetable
TT = readtimetable(filename) is readtable with a timestamp promoted to row times: the first datetime or duration column becomes the row times, and the rest become the variables. It accepts text, spreadsheet, JSON (R2026a), XML and compressed files, and an options object from detectImportOptions. Alongside an options object it honours ReadVariableNames, RowTimes, SampleRate, TimeStep and StartTime (and DateLocale, Encoding, Sheet and UseExcel where they apply).
% Not run here (MATLAB R2026b).
opts = detectImportOptions("data/sensors.csv");
opts = setvartype(opts, "SensorID", "categorical");
TT = readtimetable("data/sensors.csv", opts);
s1 = TT(TT.SensorID == "S1", "Temperature"); % one sensor
summary(TT)
% Files without a time column: generate the row times
TT2 = readtimetable("data/steady.csv", SampleRate=2, StartTime=seconds(0));
Not run here. TT is a 6-by-2 timetable with the variables SensorID and Temperature. The TT2 call assumes a file with only data columns and builds row times at 2 samples per second starting at zero; RowTimes names an existing variable (or supplies a vector) when the first date column is not the one you want. A timestamp that MATLAB cannot recognise needs setvaropts with InputFormat first, as shown above. The subsequent work (retime, synchronize, resample) is on Timetables.
readmatrix, readcell and readvars
When the file holds only numbers, a table is more than you need.
A = readmatrix(filename) returns a numeric array. It detects the delimiter and the header lines and skips what is not numeric. OutputType chooses another type, Range limits the region, NumHeaderLines skips lines, TreatAsMissing names missing placeholders, Delimiter, DecimalSeparator, ThousandsSeparator, TrimNonNumeric, CommentStyle and the delimiter rules handle awkward text, and Sheet and Range select the spreadsheet region. An options object is allowed here too.
C = readcell(filename) reads every element into one cell of a cell array and keeps its own type: numbers as numbers, text as character vectors, dates as datetime, and gaps as missing or NaN. It is the right tool for a sheet that does not form a table: mixed blocks, notes, titles above the data. The documentation example reads ten rows of columns G to I from the sheet named "2007" of a workbook with one sheet per year: readcell("airlinesmall_subset.xlsx",Sheet="2007",Range="G2:I11").
[Var1,...,VarN] = readvars(filename) returns one workspace variable per column and is convenient to unpack two or three columns without a table.
% Not run here (MATLAB R2026b).
temps = readmatrix("data/temperature_field.csv"); % numeric grid, no header
size(temps)
block = readmatrix("data/temperature_field.csv", Range="B2:F6");
raw = readcell("data/sensors.csv"); % everything, cell by cell
[t, id, temp] = readvars("data/sensors.csv"); % three variables
Not run here. temps and block are numeric matrices of the temperature field (the file name is illustrative); raw is a 7-by-3 cell array whose first row holds the header text and whose empty temperature field is a missing value; t, id and temp are the three columns (datetime, text, double). To choose the types of the outputs of readmatrix, readcell or readvars, pass an opts object as the second input.
Source: MATLAB documentation: readmatrix, readcell, readvars
Writing: writetable, writematrix, writecell
The writers mirror the readers. writetable(T,filename) chooses the format from the extension: .txt, .dat or .csv for delimited text; .xls, .xlsm or .xlsx for spreadsheets (.xlsb only with Excel for Windows); .json and .xml. writetable(T) with no file name writes a text file named after the workspace variable and ending in .txt.
% Not run here (MATLAB R2026b).
writetable(T, "out/sensors-clean.csv"); % header row, comma delimited
writetable(T, "out/sensors.tsv", Delimiter="tab", FileType="text");
writetable(T, "out/sensors-quoted.csv", QuoteStrings="all");
writetable(T, "out/log.csv", WriteMode="append", WriteVariableNames=false);
writetable(T, "out/log.xlsx", Sheet="S1", Range="B2");
Not run here. The first call writes the variable names on the first line and one line per row. The second asks for a tab delimiter (the .tsv extension is not one the function recognises, hence FileType="text"). The third quotes every text field. The fourth appends to an existing file without repeating the header (the documentation says append and WriteVariableNames=true cannot be combined for spreadsheets). The last writes into the sheet S1 of a workbook starting at cell B2.
Source: MATLAB documentation: writetable
The name-value arguments of writetable:
| Argument | Effect |
|---|---|
|
|
|
|
|
The field delimiter for text files, for example |
|
|
|
The locale used to write month names, so that |
|
|
|
|
|
Text files: |
|
Spreadsheet target. A missing file is created with the written table in the first sheet. |
|
Spreadsheet details: start Excel on Windows, adjust column widths, keep the cell formatting that already exists. |
|
JSON output. |
|
XML output. |
writematrix(A,filename) writes a homogeneous array to a text or spreadsheet file; it overwrites an existing text file unless WriteMode="append", accepts Delimiter, QuoteStrings, Encoding, Sheet, Range and the spreadsheet options, and does not support sparse matrices. writecell and writetimetable do the same for cell arrays and timetables.
A written file is not the table
The writetable documentation lists cases where the file does not represent the table exactly, so that readtable(writetable(T)) is not T. Numbers are written with the long g format; categorical and character variables are written as unquoted characters; a variable with several columns is written as several columns whose headings get a suffix (BloodPressure_1, BloodPressure_2); and Inf becomes 65535 in Excel, while NaN, NaT, undefined categoricals and missing strings become empty cells. For Excel, datetimes before the year 1900 (or 1904) are written as text. To save a table so that it comes back exactly (types, row names, properties, categorical and datetime variables), save it in a MAT-file with save; see Workspace Variables and MAT-Files. Nested tables cannot be written: split them first with splitvars.
Source: MATLAB documentation: writetable
Spreadsheets
A spreadsheet is a container of sheets, each a grid of cells. The readers and writers take the same two arguments for locating data:
-
Sheet: the worksheet, by name ("2007") or by position (1, the default).sheetnames(filename)returns the names as a string array: for the documentation’s example workbook it returns thirteen names, "1996" through "2008". -
Range: the cells to read or write, as an Excel range ("C2:E6"), a start cell ("B2"when writing), or a whole-column range ("A:C").
% Not run here (MATLAB R2026b).
file = "data/plate-runs.xlsx";
sheets = sheetnames(file); % ["Run1" "Run2" ...]
T1 = readtable(file, Sheet="Run1"); % whole sheet, header in row 1
T2 = readtable(file, Sheet=2, Range="C2:E6", ReadVariableNames=false);
M = readmatrix(file, Sheet="Run1", Range="B2:F6"); % numbers only
% Several sheets
runs = cell(numel(sheets), 1);
for k = 1:numel(sheets)
runs{k} = readtable(file, Sheet=sheets(k));
end
Not run here. The first read takes the first row as variable names; the second reads a 5-by-3 block starting at C2 and names its variables Var1 to Var3, because the first row of the range is data; runs holds one table per sheet. With an opts object, set the area on the object (opts.Sheet, opts.DataRange, opts.VariableNamesRange) so the same recipe is reusable, as in the documentation’s patients.xls example where opts.SelectedVariableNames restricts the read to two columns.
Points that decide whether spreadsheet code works on a given machine:
-
Platform. Without Microsoft Excel for Windows, and on MATLAB Online, only
.xls,.xlsm,.xlsx,.xltmand.xltxare read (and, for writing,.xls,.xlsmand.xlsx)..xlsband.odsneed Excel on Windows. Write portable code to the common formats. -
Merged cells.
MergedCellColumnRule("placeleft"default,"placeright","duplicate","omitrow"or"error") andMergedCellRowRule("placetop"default,"placebottom","duplicate","omitvar"or"error") say where the value of a merged cell goes. These rules were extended in R2024b. -
Dates. Excel stores dates as serial numbers.
readtablereturnsdatetimeby default;DatetimeType="exceldatenum"keeps the numbers. The 1900 and 1904 date systems differ, andwritetablewrites dates before 1900 (or 1904) as text. -
Speed. The reference page notes that large XLSX files can load slowly, and that Microsoft recommends the XLSB format for better performance.
-
Merged headers and notes. A sheet with a title above the table needs
RangeorNumHeaderLines; a sheet that is not a table at all is a job forreadcell.
Google Sheets (R2026b)
Since R2026b the same functions read and write Google Sheets spreadsheets. The functions named in the release notes are readtable, writetable, readmatrix, writematrix, readcell, writecell, readtimetable, writetimetable and sheetnames; instead of a file name, pass the spreadsheet URL or the spreadsheet ID. Sheet and Range choose the region.
% Not run here, and not runnable without a Google account and credentials.
url = "https://docs.google.com/spreadsheets/d/<SPREADSHEET_ID>";
T = readtable(url); % first sheet
T = readtable(url, Sheet="Sheet2", Range="A1:D10"); % part of another sheet
writetable(T, url); % write to an existing spreadsheet
Not run here. <SPREADSHEET_ID> is a placeholder; use your own spreadsheet. Before the first call, authorise MATLAB once (the steps, in short):
-
In the Google Cloud Console, create a project, configure the OAuth consent screen, create an OAuth client ID of type "Desktop app" and download the credentials as a JSON file; enable the Google Sheets API for the project.
-
In desktop MATLAB open the Connections panel (Home tab, Environment section), select Google Sheets, browse to the credentials file, choose the scope (Read or Read & Write) and complete the authorisation in the browser.
The client secret in that JSON file is a credential: keep it out of the repository and out of your code, and see Secrets and Protecting Code. The documentation lists the following limits: going over Google’s quota limit is an error; a spreadsheet may hold at most 10 million cells across all sheets, and a write can fail past it; a new spreadsheet cannot be created programmatically in a Shared drive (create it by hand first); and writing wide tables can be slow when columns are auto-fitted, which AutoFitWidth=false avoids.
Other sources readtable can read
readtable is a general front end for "table-like data", and the list has grown with the releases (all from the Version History of the reference page):
| Source | How | Since |
|---|---|---|
XML file, and files from the internet |
|
R2021a |
HTML page, Microsoft Word document |
|
R2021b |
Compressed and archived data |
|
R2025a |
Merged spreadsheet cells |
|
R2024b |
JSON file |
|
R2026a |
S3 and Azure via HTTPS URLs |
|
R2026b |
JSON as a table is the same R2026a feature described with readstruct and jsondecode on JSON, XML and Web Access. A weboptions object can be passed with WebOptions when the URL needs headers or credentials; do not put real credentials in code (use secretID objects or environment variables, and placeholders in published examples).
The Import Tool
The Import Tool is the interactive front end to the same functions. It previews a file (or the clipboard), lets you select rows, columns or variables, rename variables, set their types, replace unimportable or empty cells, and then imports the data, or generates code (a script or a function) that reproduces the import. That generated function is a convenient way to learn the options object for a file you will read repeatedly.
-
Open it from the Home tab of the toolstrip (Variable section, Import Data), or from the command line with
uiimportoruiimport(filename).uiimport -fileshows the file selection dialog first anduiimport -pastespecialimports from the clipboard. -
It reads text files, spreadsheets, MAT-files, images, audio and video, and HDF5 and netCDF files.
-
Since R2023a a Live Editor task, "Import Data", offers the same choices inside a live script and generates the code for the file you choose.
The tool is convenient for exploration. Production code should call the functions, because a script that opens a dialog is not reproducible. Use the Import Tool to find the settings, copy the generated code, and keep that.
Base-language reading and writing
The functions on this page are not part of the minimal core of the language that Octave implements. For small, regular files the low-level tools work in MATLAB and in Octave, and are what the snippet below uses: fprintf writes the file and textscan reads formatted columns into a cell array. See Low-Level File I/O and the File System for fopen, fprintf and textscan in detail.
d = tempname(pwd); mkdir(d);
f = fullfile(d, "sensors.csv");
fid = fopen(f, "w");
fprintf(fid, "Time,SensorID,Temperature\n");
fprintf(fid, "2026-01-15 10:00:00,S1,21.5\n");
fprintf(fid, "2026-01-15 10:00:30,S2,22.1\n");
fprintf(fid, "2026-01-15 10:01:00,S1,21.6\n");
fprintf(fid, "2026-01-15 10:01:30,S2,\n");
fprintf(fid, "2026-01-15 10:02:00,S1,21.8\n");
fprintf(fid, "2026-01-15 10:02:30,S2,22.4\n");
fclose(fid);
fid = fopen(f, "r");
c = textscan(fid, "%s %s %f", "Delimiter", ",", "HeaderLines", 1, "EmptyValue", NaN);
fclose(fid);
disp(size(c{1}))
disp(c{3}')
disp(nnz(isnan(c{3})))
rmdir(d, "s");
Octave 11.3.0 output (MATLAB’s layout may differ in spacing):
6 1
21.5000 22.1000 21.6000 NaN 21.8000 22.4000
1
The run reads the six-row sensors.csv as three columns (the third as numbers, with the empty field read as NaN through EmptyValue) and counts the one gap. The temporary folder is created inside the working directory and removed at the end. In MATLAB, the same job is readtable and needs no format string. A purely numeric matrix goes through a CSV file with writematrix and readmatrix, the replacements for the older dlmwrite, dlmread and csvwrite:
% Not run here (MATLAB R2026b; Octave 11.3.0 has neither function).
M = [1 2 3; 4 5 6];
g = fullfile(tempdir, "m.csv");
writematrix(M, g); % comma-delimited, chosen from the .csv extension
isequal(readmatrix(g), M) % true: the file holds 1,2,3 and 4,5,6
delete(g)
Common errors and pitfalls
The exact messages and identifiers depend on the release and were not run here; the descriptions give the cause.
-
File not found. A relative name is resolved against the current folder and the MATLAB path. Check
pwd,isfile(name)and the spelling. For files you ship with a project, build the path withfullfilefrom a known root; see The Search Path, Startup and Files. -
Wrong delimiter or wrong header detected. A European CSV with semicolons and decimal commas, or a file with a preamble, defeats the detection and yields one wide text variable or shifted names. Set
Delimiter,DecimalSeparator,NumHeaderLinesorDataLinesexplicitly, or usedelimitedTextImportOptions. -
Detection on a tiny file. The documentation warns that format detection is less reliable on small data sets. Do not trust the types guessed from a six-row sample; set them with
setvartype. -
Variable names change. With the default
VariableNamingRule="modify","Mean temp ©"becomesMean_temp_C_. Use"preserve"and dynamic dot notation, orrenamevars, when downstream code needs the original text. Table variable names are described on Tables. -
Text read as cell arrays. The default is
TextType="char", so text columns come back as cell arrays of character vectors; comparing with==fails. Ask for"string"or usesetvartype. -
Dates that do not parse. A format that differs from the file gives
NaT(with the defaultImportErrorRule="fill"and no warning). GiveInputFormat, then count withsum(isnat(T.Time))after the read. -
Silent row loss.
MissingRule="omitrow"andImportErrorRule="omitrow"drop rows without a message. Compareheight(T)with the number of data lines. -
Missing-value placeholders. A logger that writes
-999orNAproduces numbers or text, not gaps. Declare them withTreatAsMissingor standardise afterwards as shown on Missing Data. -
Name-value arguments next to an options object. Only a few are honoured; others are ignored or rejected. Put the setting on
opts. -
Round trips.
writetablefollowed byreadtabledoes not restore categorical, string and multicolumn variables exactly; save a MAT-file when you need the exact table. -
Google Sheets without authorisation. The first call fails until the Connections panel step has been done; it cannot be done from a MATLAB session without a desktop (batch and CI jobs need a saved authorisation or a different route).
Where older books differ
-
Books before R2013b read tabular data with
importdata,textscan,csvread,dlmreadandxlsread, and keep results in matrices, cell arrays and structure arrays.readtable(R2013b) was the first function to return a table;readmatrix,readcell,readvarsandreadtimetable(R2019a) are the current counterparts ofcsvread,dlmread,xlsreadand friends. The old functions still run: since R2019a the reference pages ofcsvread,dlmreadandxlsreadmark them as not recommended (pointing toreadmatrix, and forxlsreadalsoreadtableandreadcell) and state that there are no plans to remove them. -
The
xlsreadandxlswritepair predates this family. Without Excel for Windows (or in MATLAB Online)xlsreadworks in abasicmode with fewer features, and its interactive andprocessFcnforms need Excel on Windows.readtableandreadmatrixread spreadsheets without Excel by default since R2019b, so code that depended on Excel behaviour (named ranges, formulas) needs a second look. -
In older code the options are comma-separated name-value pairs with quoted names (
'ReadVariableNames',false). TheName=Valuesyntax arrived in R2021a; both work, but do not mix them in one call. -
PreserveVariableNameswas replaced byVariableNamingRulein R2020b; a book that shows the old option describes behaviour that still maps to"preserve". -
Books written before
detectImportOptions(R2016b) set the format withtextscanformat strings; the import options objects replace the format string with named properties. -
No pre-2023 book covers Google Sheets (R2026b), compressed files read directly (R2025a), JSON as a table (R2026a), the Live Editor Import Data task (R2023a), or reading HTML and Word tables (R2021b).