Jonathan Small
Jonathan Small

Reputation: 1079

C# application with mail merge generates Aspose Error! Bar code generator is not set

I have a C# application which makes use of Aspose to execute a mail merge and generate a qr code on the resulting document. When I execute the merge and view the resulting document, in the location where the qr code should be I see an error message which states

Error! Bar code generator is not set.

This is the code that I am using to execute the mail merge:

System.Data.DataTable dt = _repoForm.GetProtestCasesTempate(modelList, CertificationDate, SignedBy);
Aspose.Words.License license = new Aspose.Words.License();
license.SetLicense("Aspose.Total.xxxxxx.lic");
Aspose.Pdf.License oPdfLicense = new Aspose.Pdf.License();
oPdfLicense.SetLicense("Aspose.Total.xxxxxx.lic");
Aspose.BarCode.License oBarCodeLicense = new Aspose.BarCode.License();
oBarCodeLicense.SetLicense("Aspose.Total.xxxxxx.lic");

MemoryStream finalOutStream = new MemoryStream();
Aspose.Words.Document retainerDoc;
string PathToTemplate = "";
if (dt.Rows.Count > 0)
{
    IEnumerable<letter_templates> TemplatePath = _repo.FetchLetterTemplates("Protest");
    foreach (var item in TemplatePath)
    {
        PathToTemplate = item.full_file_path;
    }
    Aspose.Words.Document template = new Aspose.Words.Document(PathToTemplate);
    MemoryStream outStream = new MemoryStream();
    template.FieldOptions.BarcodeGenerator = new CustomBarcodeGenerator();
    template.MailMerge.Execute(dt);
    template.Save(outStream, Aspose.Words.SaveFormat.Docx);
    retainerDoc = new Aspose.Words.Document(outStream);
    retainerDoc.Save(finalOutStream, Aspose.Words.SaveFormat.Pdf);
    finalOutStream.Seek(0, SeekOrigin.Begin);
}

This is what my word docx file looks like:

enter image description here

And this is what I get when I execute the code:

enter image description here

The section where the 2 merge fields are in the bottom right corner where I want to put the qr code is contained within a text box. Could the size of the text box be restricting the processes ability to generate the qr code?

I can not figure out why I am getting a bar code generator is not set error message.

Any help is greatly appreciated.

Upvotes: 0

Views: 186

Answers (1)

Alexey Noskov
Alexey Noskov

Reputation: 1960

Aspose.Words does not render DISPLAYBARCODE fields itself. To render such fields you should specify a custom barcode generator. For example see Aspose.Words documentation: https://reference.aspose.com/words/net/aspose.words.fields/fieldoptions/barcodegenerator/

The code should look like this:

Document doc = new Document(@"C:\Temp\in.docx");
doc.FieldOptions.BarcodeGenerator = new CustomBarcodeGenerator();
doc.UpdateFields();
doc.Save(@"C:\Temp\out.pdf");

Where CustomBarcodeGenerator is IBarcodeGenerator implementation. For example here is an implementation using Aspose.Barcode, but you can use any other barcode generator:

public class CustomBarcodeGenerator : IBarcodeGenerator
{
    /// <summary>
    /// Converts barcode image height from Word units to Aspose.BarCode units.
    /// </summary>
    /// <param name="heightInTwipsString"></param>
    /// <returns></returns>
    private static float ConvertSymbolHeight(string heightInTwipsString)
    {
        // Input value is in 1/1440 inches (twips)
        int heightInTwips = TryParseInt(heightInTwipsString);

        if (heightInTwips == int.MinValue)
            throw new Exception("Error! Incorrect height - " + heightInTwipsString + ".");

        // Convert to mm
        return (float)(heightInTwips * 25.4 / 1440);
    }

    /// <summary>
    /// Converts barcode image color from Word to Aspose.BarCode.
    /// </summary>
    /// <param name="inputColor"></param>
    /// <returns></returns>
    private static Color ConvertColor(string inputColor)
    {
        // Input should be from "0x000000" to "0xFFFFFF"
        int color = TryParseHex(inputColor.Replace("0x", ""));

        if (color == int.MinValue)
            throw new Exception("Error! Incorrect color - " + inputColor + ".");

        return Color.FromArgb(color >> 16, (color & 0xFF00) >> 8, color & 0xFF);

        // Backward conversion -
        //return string.Format("0x{0,6:X6}", mControl.ForeColor.ToArgb() & 0xFFFFFF);
    }

    /// <summary>
    /// Converts bar code scaling factor from percent to float.
    /// </summary>
    /// <param name="scalingFactor"></param>
    /// <returns></returns>
    private static float ConvertScalingFactor(string scalingFactor)
    {
        bool isParsed = false;
        int percent = TryParseInt(scalingFactor);

        if (percent != int.MinValue && percent >= 10 && percent <= 10000)
            isParsed = true;

        if (!isParsed)
            throw new Exception("Error! Incorrect scaling factor - " + scalingFactor + ".");

        return percent / 100.0f;
    }

    /// <summary>
    /// Implementation of the GetBarCodeImage() method for IBarCodeGenerator interface.
    /// </summary>
    /// <param name="parameters"></param>
    /// <returns></returns>
    public Image GetBarcodeImage(BarcodeParameters parameters)
    {
        if (parameters.BarcodeType == null || parameters.BarcodeValue == null)
            return null;

        BarcodeGenerator generator = new BarcodeGenerator(EncodeTypes.QR);

        string type = parameters.BarcodeType.ToUpper();

        switch (type)
        {
            case "QR":
                generator = new BarcodeGenerator(EncodeTypes.QR);
                break;
            case "CODE128":
                generator = new BarcodeGenerator(EncodeTypes.Code128);
                break;
            case "CODE39":
                generator = new BarcodeGenerator(EncodeTypes.Code39Standard);
                break;
            case "EAN8":
                generator = new BarcodeGenerator(EncodeTypes.EAN8);
                break;
            case "EAN13":
                generator = new BarcodeGenerator(EncodeTypes.EAN13);
                break;
            case "UPCA":
                generator = new BarcodeGenerator(EncodeTypes.UPCA);
                break;
            case "UPCE":
                generator = new BarcodeGenerator(EncodeTypes.UPCE);
                break;
            case "ITF14":
                generator = new BarcodeGenerator(EncodeTypes.ITF14);
                break;
            case "CASE":
                generator = new BarcodeGenerator(EncodeTypes.None);
                break;
        }

        if (generator.BarcodeType.Equals(EncodeTypes.None))
            return null;

        generator.CodeText = parameters.BarcodeValue;

        if (generator.BarcodeType.Equals(EncodeTypes.QR))
            generator.Parameters.Barcode.CodeTextParameters.TwoDDisplayText = parameters.BarcodeValue;

        if (parameters.ForegroundColor != null)
            generator.Parameters.Barcode.BarColor = ConvertColor(parameters.ForegroundColor);

        if (parameters.BackgroundColor != null)
            generator.Parameters.BackColor = ConvertColor(parameters.BackgroundColor);

        if (parameters.SymbolHeight != null)
        {
            generator.Parameters.ImageHeight.Pixels = ConvertSymbolHeight(parameters.SymbolHeight);
            generator.Parameters.AutoSizeMode = AutoSizeMode.None;
        }

        generator.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.None;

        if (parameters.DisplayText)
            generator.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.Below;

        generator.Parameters.CaptionAbove.Text = "";

        const float scale = 2.4f; // Empiric scaling factor for converting Word barcode to Aspose.BarCode
        float xdim = 1.0f;

        if (generator.BarcodeType.Equals(EncodeTypes.QR))
        {
            generator.Parameters.AutoSizeMode = AutoSizeMode.Nearest;
            generator.Parameters.ImageWidth.Inches *= scale;
            generator.Parameters.ImageHeight.Inches = generator.Parameters.ImageWidth.Inches;
            xdim = generator.Parameters.ImageHeight.Inches / 25;
            generator.Parameters.Barcode.XDimension.Inches =
                generator.Parameters.Barcode.BarHeight.Inches = xdim;
        }

        if (parameters.ScalingFactor != null)
        {
            float scalingFactor = ConvertScalingFactor(parameters.ScalingFactor);
            generator.Parameters.ImageHeight.Inches *= scalingFactor;

            if (generator.BarcodeType.Equals(EncodeTypes.QR))
            {
                generator.Parameters.ImageWidth.Inches = generator.Parameters.ImageHeight.Inches;
                generator.Parameters.Barcode.BarHeight.Inches = xdim * scalingFactor;
                generator.Parameters.Barcode.QR.AspectRatio = scalingFactor;
            }

            generator.Parameters.AutoSizeMode = AutoSizeMode.None;
        }

        return generator.GenerateBarCodeImage();
    }

    /// <summary>
    /// Implementation of the GetOldBarcodeImage() method for IBarCodeGenerator interface.
    /// </summary>
    /// <param name="parameters"></param>
    /// <returns></returns>
    public Image GetOldBarcodeImage(BarcodeParameters parameters)
    {
        if (parameters.PostalAddress == null)
            return null;

        BarcodeGenerator generator = new BarcodeGenerator(EncodeTypes.Postnet)
        {
            CodeText = parameters.PostalAddress
        };

        // Hardcode type for old-fashioned Barcode
        return generator.GenerateBarCodeImage();
    }

    /// <summary>
    /// Parses an integer using the invariant culture. Returns Int.MinValue if cannot parse.
    /// 
    /// Allows leading sign.
    /// Allows leading and trailing spaces.
    /// </summary>
    public static int TryParseInt(string s)
    {
        return double.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out double temp)
            ? CastDoubleToInt(temp)
            : int.MinValue;
    }

    /// <summary>
    /// Casts a double to int32 in a way that uint32 are "correctly" casted too (they become negative numbers).
    /// </summary>
    public static int CastDoubleToInt(double value)
    {
        long temp = (long)value;
        return (int)temp;
    }

    /// <summary>
    /// Try parses a hex String into an integer value.
    /// on error return int.MinValue
    /// </summary>
    public static int TryParseHex(string s)
    {
        return int.TryParse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int result)
            ? result
            : int.MinValue;
    }
}

and Github: https://github.com/aspose-words/Aspose.Words-for-.NET/blob/b0f89864f49794ab15f264e35d41856b667143dd/Examples/ApiExamples/ApiExamples/CustomBarcodeGenerator.cs

Upvotes: -2

Related Questions