C++ code for mail merge
A classic task!
Mail merge is a process of combining a template document with a dataset to produce multiple output documents. Here's a basic C++ code example that demonstrates a simple mail merge using a template document and a CSV file as the dataset.
Note: This example uses the fstream
library for file input/output and the string
library for string manipulation.
mail_merge.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
// Structure to represent a record in the dataset
struct Record {
std::string name;
std::string email;
// Add more fields as needed
};
// Function to read the dataset from a CSV file
std::vector<Record> readDataset(const std::string& filename) {
std::vector<Record> records;
std::ifstream file(filename);
if (!file) {
std::cerr << "Error opening file: " << filename << std::endl;
return records;
}
std::string line;
while (std::getline(file, line)) {
Record record;
std::stringstream ss(line);
std::string field;
while (std::getline(ss, field, ',')) {
if (field.empty()) continue;
if (field.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")!= std::string::npos) {
// Handle quoted fields (e.g., "John Doe")
field = field.substr(1, field.size() - 2);
}
if (field == "name") {
record.name = field;
} else if (field == "email") {
record.email = field;
// Add more field handling as needed
}
}
records.push_back(record);
}
file.close();
return records;
}
// Function to perform the mail merge
void mailMerge(const std::string& templateFile, const std::string& outputDir, const std::vector<Record>& records) {
std::ifstream templateFilestream(templateFile);
if (!templateFilestream) {
std::cerr << "Error opening template file: " << templateFile << std::endl;
return;
}
std::string line;
while (std::getline(templateFilestream, line)) {
for (const auto& record : records) {
std::stringstream ss(line);
std::string word;
while (std::getline(ss, word, ' ')) {
if (word.find_first_of("{{")!= std::string::npos) {
// Replace placeholders with actual values
if (word == "{{name}}") {
word = record.name;
} else if (word == "{{email}}") {
word = record.email;
// Add more placeholder handling as needed
}
}
std::cout << word << " ";
}
std::cout << std::endl;
}
}
templateFilestream.close();
}
int main() {
// Set the input file and output directory
const std::string datasetFile = "dataset.csv";
const std::string templateFile = "template.txt";
const std::string outputDir = "output";
// Read the dataset from the CSV file
std::vector<Record> records = readDataset(datasetFile);
// Perform the mail merge
mailMerge(templateFile, outputDir, records);
return 0;
}
How it works:
- The
readDataset
function reads the dataset from a CSV file and stores it in a vector ofRecord
structures. - The
mailMerge
function takes the template file, output directory, and dataset as input. It reads the template file line by line and replaces placeholders (e.g.,{{name}}
) with actual values from the dataset. - The
main
function sets the input file and output directory, reads the dataset from the CSV file, and performs the mail merge using themailMerge
function.
Example usage:
- Create a CSV file named
dataset.csv
with the following content:name,email John Doe,[email protected] Jane Smith,[email protected]
- Create a template file named
template.txt
with the following content:Dear {{name}}, Thank you for your interest in our product. You can reach us at {{email}}. Best regards, [Your Name]
- Compile and run the
mail_merge.cpp
code. - The output will be a set of merged documents in the
output
directory, each with the corresponding values from the dataset.
Note that this is a basic example, and you may need to modify the code to suit your specific requirements. Additionally, this example assumes that the placeholders in the template file are in the format {{field_name}}
. You may need to adjust the placeholder handling code accordingly.