LaTeX/Serial letter

A serial letter is used in administrative workflows to create individualized letters to a specific number of people. A serial letter approach in this setting consists at least of 3 main files:

  • data file (e.g. CSV-file) which contains specific data, that is inserted in individualized letters to the recipient.
  • LaTeX template that contain the letter as static text blocks that are inserted in all letters and the marker command that are replaced with content of data file.
  • LaTeX Main Document that performs the iteration over all records (i.e. line) in the data file.

Data File edit

Assume we have a data file mydata.db that contains all the addresses of the recipients of the letter.

 Mr|Herbert|Miller|A-street 5|98765|A-Town|321
 Mrs|Lisa|Meyer|B-road 67|12345|B-City|500
 Mr|Tom|Smith|C-place 12|66666|C-Village|220

Every line represents the data for one letter and each entry of a record is separated by a pipe symbol "|". The record separator can be replaced by another symbol. We did not use the comma "," as in comma separated value (CSV) to allow the comma "," also in text fragments as the following example shows.

 Mr|Herbert|Miller|A-street 5, entrance A1|98765|A-Town|321

In general you could used also other separator symbols. Keep in mind that you do not create a conflict with content in stored in the cells of the data file.

The data file above basically represents a table:

Data Table
Salutation Fist Name Last Name Street City Code City Name Bonus
Mr Herbert Miller A-street 5 98765 A-Town 321
Mrs Lisa Meyer B-road 67 12345 B-City 500
Mr Tom Smith C-place 12 66666 C-Village 220

LaTeX Template File edit

The LaTeX template file mytemplate.tex in this case is written in standard LaTeX without a header or tail of LaTeX document. The following document shows an example.

 {\fistname} {\lastname} \\ 
 {\street} \\ {\citycode} {\cityname}}
  
 Dear {\salutation} {\lastname},
 your salary in November includes a bonus of {\bonus}
 best regards,
 Head Administration

LaTeX Main Document edit

The LaTeX main document, that performs the iteration over all database records in the mydata.db could look like this:

\documentclass[12pt]{article} 
  \usepackage{german,latexsym,textcomp}
  %---- Define the name of the loaded database in this example "mydata.db"
  \def\databasename{mydata.db}
  %--- Now we define a command the reads a single database line and stores the data in commands
  %--- the database read command is named "\readDBline" and has 6 parameters 
  %--- according to the columns of DB
  \def\readDBline#1
 %---define a new datasource 
 \newread\datasource
 %---open file with \databasename="mydata.db"
 \openin\datasource=\databasename 
 %---- START ITERATION FOR SERIAL LETTER
 \loop
 %---- read datasource and store into \dbline
 \read\datasource  to \dbline
 %--------------------------------------------------------
 \ifeof\datasource
   \global\morefalse% 
 \else
   \expandafter\readDBline\dbline\\
   \stepcounter{CLetterCounter}
 	\ifnum \value{CLetterCounter}>1%
       %--- insert newpage after second record/letter

\newpage \fi%---

   %--- input the template file
   \input{mytemplate.tex}
   %----------------------------------------------------
 \fi%---
 \ifmore\repeat
 %--- close database \datasource
 \closein\datasource
 \end{document}

}} The main document has the following features:

  • it defines a database variable in the very beginning, so that the user can easily replace the data source for the serial letter by other data e.g. by mydata2.db.
  • the main document defines a counter. With the counter you can create a \newpage command after the second record or you can create a newpage command for name labels every 6th record. In the case set the counter back to 0 when it exceeds the threshold 6:
    \stepcounter{CLetterCounter}
  	\ifnum \value{CLetterCounter}>6%
        %insert newpage after 6th record/letter
        \setcounter{CLetterCounter}{0}
		\newpage
	\fi%