How to Generate a Custom BarCode Image for DISPLAYBARCODE Field in PDF

GenerateACustomBarCodeImage_out_17.6.docx.zip (12.0 KB)
GenerateACustomBarCodeImage_out_17.5.docx.zip (15.0 KB)

I just updated from Aspose.Words 17.2 where if I have a field in the document:
{DISPLAYBARCODE “BarCodeData” QR \s 100 \f 000000}

This will create the correct barcode when saving as PDF. When I save it as a DOC, DOCX or RTF document I can use ALT+F9 in word to switch between the FIELD data and the image version of that field. If I update the field in word, the image version will vanish as word does not know how to render that field (expected).

Now that I updated to 18.8 (also tested 18.6 and 18.7), the PDF is still generated correctly. But saved as a word document it will only contain the FIELD data and not the image version that was created.

I am using the sample code:
https://raw.githubusercontent.com/aspose-words/Aspose.Words-for-.NET/master/Examples/CSharp/Programming-Documents/Document/GenerateACustomBarCodeImage.cs

Only modification is to store the output as DOCX instead of PDF (using UpdateFields() before saving), GetBarcodeImage(…) is never called and the resulting word document contains only the FIELD info and no rendered barcode image.

Code:

public static void Run()
{
    // ExStart:GenerateACustomBarCodeImage
    // The path to the documents directory.
    string dataDir = @"C:\TEMP\";
    Document doc = new Document("barcode.docx");

    // Set custom barcode generator
    doc.FieldOptions.BarcodeGenerator = new CustomBarcodeGenerator();
    //doc.Save(dataDir + @"GenerateACustomBarCodeImage_out.pdf");
    doc.UpdateFields();
    doc.Save(dataDir + @"GenerateACustomBarCodeImage_out.docx");
    // ExEnd:GenerateACustomBarCodeImage
}

If i switch to 17.2 with the exact same code, the image version of the barcode is present. Trying versions I see that this changed (got broken?) in 17.6

Specifically related to fix
WORDSNET-14821: DISPLAYBARCODE does not render “{ PAGE } of { NUMPAGES }” in PDF
?

I have added 2 documents. 1 for 17.5 and 1 for 17.6. Open each and see that 17.5 contains an image version of the barcode while 17.6 does not (ALT+F9 to switch between field data and barcode)

As I sometimes need to create a DOCX for the user to do some modifications, the missing barcode is a problem.

@SteinGT,

Thanks for your inquiry. The GetBarcodeImage method is called when you save the document to fixed page formats such as PDF, XPS etc. Please refer to the following article.
How to Generate a Custom BarCode Image for DISPLAYBARCODE Field

So was this an unintended “bug” from previous versions that got corrected/removed?

GetBarcodeImage is also called when doing UpdateFields().

Do you have a workaround that lets me send in a default image (rendered field) for the barcode, so that it can work as previously? Like GenerateACustomBarCodeImage_out_17.5.docx.zip has. It kind of breaks things when suddenly removed.

Note that the old version word zip file contains “word\media\image1.png” which is the rendered barcode, while the new version does not have this.

Comparing old output the paragraph with the DISPLAYBARCODE contains:
FieldStart
Run
FieldSeparator
Shape (rendered barcode)
FieldEnd

The new versions contains only:
FieldStart
Run
End

I hope there is a better way to do it than the workaround I figured out. As I have not found any way to create a new FieldSeparator to add that static image.

The code adds a separator via the IF field since there seem to be no way to add a FieldSeparator (as its internal). Then after the separator the content is replaced with a SHAPE of the barcode. This is pretty dirty code and I hope there is a better solution to this.

    private static void AddStaticBarcodeImageForWord(Document doc)
    {

        var builder = new DocumentBuilder(doc);

        var fields = doc.SelectNodes("//FieldStart").Cast<Node>().ToList();

        foreach (Node field in fields)
        {
            builder.MoveTo(field.NextSibling);
            string runText = "";
            Node separatorNode = null;
            while (!(builder.CurrentNode is FieldEnd))
            {
                if (builder.CurrentNode is FieldSeparator) separatorNode = builder.CurrentNode;
                if (builder.CurrentNode is Run) runText += (builder.CurrentNode as Run).Text;
                builder.MoveTo(builder.CurrentNode.NextSibling);
            }

            if (runText.Trim().StartsWith("DISPLAYBARCODE "))
            {

                var fieldEndNode = builder.CurrentNode;
                if (separatorNode == null)
                {
                    var fieldIf = builder.InsertField("IF ");
                    fieldEndNode.Remove();
                    builder.MoveToField(fieldIf, false);
                    while (!(builder.CurrentNode is FieldEnd) && !(builder.CurrentNode is FieldSeparator))
                    {
                        if (builder.CurrentNode is FieldEnd) return; //Unexpected. No FieldSeparator
                        var node = builder.CurrentNode;
                        builder.MoveTo(builder.CurrentNode.NextSibling);
                        node.Remove();
                    }

                    separatorNode = builder.CurrentNode;
                    builder.MoveTo(builder.CurrentNode.NextSibling);
                }


                //Remove old content after Separator
                while (!(builder.CurrentNode is FieldEnd))
                {
                    var node = builder.CurrentNode;
                    builder.MoveTo(builder.CurrentNode.NextSibling);
                    node.Remove();
                }

                builder.MoveTo(separatorNode);
                builder.MoveTo(builder.CurrentNode.NextSibling);
                var barcodeElements = runText.Trim(' ').Split(' ');
                var barcodeText = barcodeElements[1].Trim('\"');
                var barcodeType = barcodeElements[2];
                var barcodeShape = new CustomBarcodeGenerator().GetBarcodeImage(new BarcodeParameters() { BarcodeType = barcodeType, BarcodeValue = barcodeText });
                builder.InsertImage(barcodeShape);
            }
        }
    }

@SteinGT,

Could you please ZIP and attach your expected output Word document? We will then provide you code example according to your requirement.

Could you please share the Aspose.Words’ version that you are using for it?

I am using version Aspose Words 18.7.

Expected output:GenerateACustomBarCodeImage_out_17.5.docx.zip (in first post)
Current output: GenerateACustomBarCodeImage_out_17.6.docx.zip (in first post)

As explained, expected output should contain a DISPLAYBARCODE field with a separator that contains the rendered image like it did in older version:

FieldStart
Run (DISPLAYBARCODE …)
FieldSeparator
Shape (rendered image of barcode)
FieldEnd

In newer versions of Aspose.Words, FieldSeparator and Shape have been removed.

@SteinGT,

Thanks for your inquiry. We have tested the scenario using latest version of Aspose.Words for .NET 18.8 with following code example. We have not found the shared issue. We have attached the input and output documents with this post for your kind reference. Docs.zip (46.9 KB)

Document doc = new Document(MyDir + "barcode.docx");

doc.FieldOptions.BarcodeGenerator = new CustomBarcodeGenerator();
doc.UpdateFields();

doc.Save(MyDir + @"18.8.docx");

Could you please share the code and input document that you are using at your end? We will investigate the issue and provide you more information on it.

Your source doc already has the correct barcode image to begin with . So it just saves it out again (no changes).
That works for me as well.

Check the docx zip contents and you will find the original image1.jpg file there in both your input and output.

You will need to have a document containing of only the FIELD definition (that was never processes by Aspose Words to begin with).

Please use GenerateACustomBarCodeImage_out_17.6.docx as the input. This only has the FIELD definition.

Added my source code:
AsposeNuGetProjectConsoleApp1.zip (23.8 KB)

@SteinGT,

Thanks for your inquiry. We have logged this problem in our issue tracking system as WORDSNET-17322. You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

@SteinGT,

Thanks for your patience. It is to inform you that the issue which you are facing is actually not a bug in Aspose.Words. So, we have closed this issue (WORDSNET-17322) as ‘Not a Bug’.

The IBarcodeGenerator.GetBarcodeImage method is not called during Document.UpdateFields because BARCODE field does not have a result stored in DOM (i.e. it is a fake result field). MS Word updates such fields automatically when document is opened or field code is changed. That is why the IBarcodeGenerator.GetBarcodeImage method is only called when document is exported into fixed page formats (like PDF) or field is replaced with its result via the Field.Unlink or Document.UnlinkFields method. Please note that Aspose.Words mimics the behavior of MS Word. MS Word acts the same way:

<w:body>
<w:p w:rsidR=“00F9543D” w:rsidRDefault=“006D3B94”>
<w:r>
<w:fldChar w:fldCharType=“begin”/>
</w:r>
<w:r w:rsidRPr=“006B1C84”>
<w:rPr>
<w:lang w:val=“en-US”/>
</w:rPr>
<w:instrText>DISPLAYBARCODE “BarCodeData” QR \s 100 \f 000000</w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType=“end”/>
</w:r>
</w:p>