Building a Batch Label Printing Application in C# with Bartender Integration

System Architecture Design

Core Module Breakdown

public class LabelPrintingSystem {
    private IDataSource _dataSource;
    private ITemplateRenderer _templateRenderer;
    private IPrintManager _printManager;
    private ILogger _logger;
}

Technology Recommendations

  • Template Engine: Bartender (recommended) or SoftCode
  • Data Interface: ADO.NET (databases) / EPPlus (Excel)
  • Print Control: BarTender COM components or SDK
  • UI Framework: WinForms / WPF

Key Implementation Steps

1. Data Preparation and Loading

// Database data loading example
public class SqlDataSource : IDataSource {
    public List<LabelRecord> Fetch(string connectionString) {
        using (var connection = new SqlConnection(connectionString)) {
            var command = new SqlCommand("SELECT * FROM Labels", connection);
            connection.Open();
            return command.ExecuteReader().ConvertToList<LabelRecord>();
        }
    }
}

// Excel data loading example
public class SpreadsheetDataSource : IDataSource {
    public List<LabelRecord> Fetch(string filePath) {
        using (var document = new ExcelPackage(new FileInfo(filePath))) {
            return document.Workbook.Worksheets[0].ConvertToList<LabelRecord>();
        }
    }
}

2. Bartender Template Integration

// Template engine initialization
var renderer = new BartenderTemplateRenderer();
renderer.LoadTemplate("LabelTemplate.btw");

// Data binding
renderer.BindData("ProductCode", record.Code);
renderer.BindData("Barcode", record.Barcode);
renderer.BindData("BatchNo", record.Batch);

3. Core Batch Printing Logic

public void ExecuteBatchPrint(List<LabelRecord> records) {
    var printTask = new PrintTask {
        PrinterName = "Zebra ZT410",
        Copies = 3,
        PaperSize = PaperSize.Custom(6, 4)
    };

    foreach (var record in records) {
        renderer.SetVariable("ProductName", record.Name);
        renderer.SetVariable("ExpiryDate", record.Expiry.ToString("yyyy-MM-dd"));
        
        if (record.NeedsPrint) {
            printTask.AddPage(renderer.GeneratePage());
        }
    }
    
    printTask.SendToPrinter();
}

Advanced Features

1. Dynamic Template Selection

public class TemplateSelector {
    public string ResolveTemplate(LabelRecord record) {
        return record.Category switch {
            ProductCategory.Food => "FoodLabel.btw",
            ProductCategory.Pharmaceutical => "PharmaLabel.btw",
            _ => "DefaultLabel.btw"
        };
    }
}

2. Print Queue Management

public class PrintQueueManager {
    private Queue<PrintTask> _queue = new Queue<PrintTask>();
    
    public void EnqueueTask(PrintTask task) {
        _queue.Enqueue(task);
    }
    
    public void ProcessQueue() {
        while (_queue.Count > 0) {
            var task = _queue.Dequeue();
            task.Execute();
        }
    }
}

3. Error Handling Mechanism

public class PrintErrorHandler {
    public void Handle(Exception ex, PrintTask task) {
        _logger.LogError($"Print failure: {task.Id} - {ex.Message}");
        
        if (task.RetryCount < 3) {
            task.RetryCount++;
            _printQueueManager.EnqueueTask(task);
        }
    }
}

Performance Optimization Strategies

1. Print Task Merging

public void MergePrintTasks(List<PrintTask> tasks) {
    var mergedTask = new PrintTask {
        PrinterName = tasks[0].PrinterName,
        Pages = tasks.SelectMany(t => t.Pages).ToList()
    };
    
    _printManager.Dispatch(mergedTask);
}

2. Printer Status Monitoring

public class PrinterMonitor {
    public PrinterStatus RetrieveStatus() {
        var status = new PrinterStatus();
        status.IsOnline = CheckPrinterOnline();
        status.PaperLevel = GetPaperLevel();
        status.InkLevel = GetInkLevel();
        return status;
    }
}

3. Memory Optimization

// Object pool for template instances
public class TemplatePool {
    private Queue<BartenderTemplate> _pool = new Queue<BartenderTemplate>();
    
    public BartenderTemplate AcquireTemplate() {
        return _pool.Count > 0 ? _pool.Dequeue() : LoadTemplate();
    }
    
    public void ReleaseTemplate(BartenderTemplate template) {
        _pool.Enqueue(template);
    }
}

Project Structure

LabelPrintingApp/
├── Data/
│   ├── DataLoader.cs
│   └── Models/
│       └── LabelRecord.cs
├── Templates/
│   ├── FoodLabel.btw
│   └── PharmaLabel.btw
├── Services/
│   ├── BartenderService.cs
│   └── PrintService.cs
├── UI/
│   └── MainForm.xaml
└── Utils/
    ├── Logger.cs
    └── PrinterMonitor.cs

Debugging and Testing

1. Unit Test Example

[TestClass]
public class PrintServiceTests {
    [TestMethod]
    public void TestBatchPrint() {
        var mockData = new List<LabelRecord> { /* test data */ };
        var service = new PrintService();
        
        service.Print(mockData);
        
        Assert.AreEqual(3, mockData[0].PrintCount);
    }
}

2. Stress Test Scenario

public void StressTest() {
    var stopwatch = Stopwatch.StartNew();
    var tasks = new List<Task>();
    
    for (int i = 0; i < 1000; i++) {
        tasks.Add(Task.Run(() => _printer.Print(testData)));
    }
    
    Task.WhenAll(tasks).Wait();
    stopwatch.Stop();
    
    Console.WriteLine($"1000 labels print duration: {stopwatch.ElapsedMilliseconds}ms");
}

Deployment and Maintenance

1. Installation Package Configurasion

  • Prerequisites: .NET Framework 4.8+, Bartender Runtime
  • Driver dependencies: Printer manufacturer SDKs (e.g., Zebra Designer)

2. Logging Configuration

<log4net>
  <appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="logs\\print.log" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="FileAppender" />
  </root>
</log4net>

Extension Ideas

1. Web Service Integration

[HttpPost]
public IActionResult PrintLabel([FromBody] PrintRequest request) {
    var service = new PrintService();
    service.Print(request.LabelData);
    return Ok(new { Status = "Printing" });
}

2. Mobile Suppport

  • Develop a UWP application for mobile printing
  • Integrate Bluetooth/WiFi printer connections

3. Cloud Printign Solution

public class CloudPrintService {
    public async Task PrintAsync(LabelRecord data) {
        var pdf = GeneratePdf(data);
        await _cloudStorage.UploadAsync(pdf);
        await _printService.SendToCloudPrinter();
    }
}

Tags: C# Bartender Label Printing Batch Printing Printing System

Posted on Fri, 08 May 2026 03:03:43 +0000 by fuji