Create a design by code in a web application

I’m using list&labels to integrate a web app with angular.
So I’m using webreportviewer and webreportdesigner.

I need to design from code, and the project type as ‘list’, set the header, row lines according the fields received.

Is there any way to design a report from code?

The scenario is as follows:

To make preview, you need a design, I know.

The thing is that in my application, I should be able to preview the different listings, taking into account the current view of the listing.

So when I call preview, I’ll pass the fields to view, but since there has to be a design for preview, I’ll have to have a default design, but the layout will have to be built dynamically based on the fields in the datasource that I feed dynamically.

Is there any way of creating the design (as list) and adding the headers and row lines via code?

See my reply to your comment in our blog. This can be done using the object model.

For .NET, here’s a primer:

and here’s a sample:

Would that help? Basically, you just need to create an instance of ProjectList and add your objects as required.

Of course, this also works in web applications.

Okay, I’m trying to test it and I’m trying to do something like this:

public class LLWebReportDesignerController : WebReportDesignerController
{
    public override async void OnProvideListLabel(ProvideListLabelContext provideListLabelContext)
    {
        ListLabel ll = DefaultSettings.GetListLabelInstance(provideListLabelContext.RepositoryId, null);

        GenerateLLProject(ll);

        provideListLabelContext.NewInstance = ll;
    }

    public override void OnProvideRepository(ProvideRepositoryContext provideFileRepositoryContext)
    {
        provideFileRepositoryContext.FileRepository = DefaultSettings.GetBaseRepository();
    }

    public override void OnProvideWebReportDesignerSessionOptions(ProvideWebReportDesignerSessionOptionsContext provideWebReportDesignerSessionOptionsContext)
    {
        base.OnProvideWebReportDesignerSessionOptions(provideWebReportDesignerSessionOptionsContext);
    }

    public override void OnProvideProhibitedActions(ProvideProhibitedActionsContext provideProhibitedActionsContext)
    {
        foreach (WebReportDesignerAction action in DefaultSettings.GetProhibitedActions())
        {
            provideProhibitedActionsContext.ProhibitedActions.Add(action);
        }
    }

    private void GenerateLLProject(ListLabel ll)
    {
        try
        {
            //D: Neues DOM-Projekt vom Typen LlProject.List erzeugen
            //US: Create new DOM project, type LlProject.List
            using (ProjectList proj = new ProjectList(ll))
            {
                //D: Dateinamen und Dateizugriffsoptionen setzen
                //US: Set file name and file access options
                proj.Open("repository://{2BB00D79-5124-46D8-BFF1-C8460014DA1D}", LlDomFileMode.Create, LlDomAccessMode.ReadWrite);

                //D: Standardschrift und -größe setzen
                //US: Set default font and size
                proj.Settings.DefaultFont.FaceName = "\"Calibri\"";
                proj.Settings.DefaultFont.Size = "12";

                //D: Designschema setzen
                //US: Set design scheme
                proj.ProjectParameters["LL.DesignScheme"].Contents = "\"COMBITCOLORWHEEL\"";

                //D: Eine neue Projektbeschreibung zuweisen
                //US: Assign new project description
                proj.ProjectParameters["LL.ProjectDescription"].Contents = "Matumona";

                //D: Ein leeres Text Objekt erstellen
                //US: Create an empty text object
                ObjectText llobjText = new ObjectText(proj.Objects);

                //D: Auslesen der Seitenkoordinaten der ersten Seite
                //US: Get the coordinates for the first page
                Size pageExtend = proj.Regions[0].Paper.Extent.Get();

                //D: Setzen von Eigenschaften für das Textobjekt. Alle Einheiten sind SCM (1/1000 mm).
                //US: Set some properties for the text object. All units are SCM (1/1000 mm).
                llobjText.Position.Set(10000, 10000, pageExtend.Width - 65000, 27000);

                //D: Hinzufügen eines Absatzes und setzen diverser Eigenschaften
                //US: Add a paragraph to the text object and set some properties
                Paragraph llobjParagraph = new Paragraph(llobjText.Paragraphs);
                llobjParagraph.Contents = string.Format("\"{0}\"", "Matumona");
                llobjParagraph.Font.Bold = "True";

                //D: Hinzufügen eines Grafikobjekts
                //US: Add a drawing object
                ObjectDrawing llobjPic = new ObjectDrawing(proj.Objects);
                llobjPic.Source.FileInfo.FileName = "Matumona";
                llobjPic.Position.Set(pageExtend.Width - 50000, 10000, pageExtend.Width - (pageExtend.Width - 40000), 27000);

                //D: Hinzufügen eines Tabellencontainers und setzen diverser Eigenschaften
                //US: Add a table container and set some properties
                ObjectReportContainer container = new ObjectReportContainer(proj.Objects);
                container.Position.Set(10000, 40000, pageExtend.Width - 20000, pageExtend.Height - 44000);

                //D: In dem Tabellencontainer eine Tabelle hinzufügen
                //US: Add a table into the table container
                SubItemTable table = new SubItemTable(container.SubItems);

                //D: Gewünschte Tabelle als Datenquelle setzen
                //US: Set required source table
                table.TableId = "Matumona";

                //D: Zebramuster für Tabelle definieren
                //US: Define zebra pattern for table
                table.LineOptions.Data.ZebraPattern.Style = "1";
                table.LineOptions.Data.ZebraPattern.Pattern = "1";
                table.LineOptions.Data.ZebraPattern.Color = "LL.Scheme.BackgroundColor0";

                //D: Eine neue Datenzeile hinzufügen mit allen ausgewählten Feldern
                //US: Add a new data line including all selected fields
                TableLineData tableLineData = new TableLineData(table.Lines.Data);
                TableLineHeader tableLineHeader = new TableLineHeader(table.Lines.Header);

                //foreach (string fieldName in listBox2.Items)
                //{
                //    string fieldWidth = (Convert.ToInt32(container.Position.Width) / listBox2.Items.Count).ToString();

                //    //D: Kopfzeile definieren
                //    //US: Define header line
                //    TableFieldText header = new TableFieldText(tableLineHeader.Fields);
                //    header.Contents = string.Format("\"{0}\"", fieldName);
                //    header.Filling.Style = "1";
                //    header.Filling.Color = "LL.Scheme.BackgroundColor2";
                //    header.Font.Bold = "True";
                //    header.Font.Color = "LL.Color.White";
                //    header.Width = fieldWidth;

                //    //D: Datenzeile definieren
                //    //US: Define data line
                //    TableFieldText tableField = new TableFieldText(tableLineData.Fields);
                //    tableField.Contents = comboBoxTable.Text + "." + fieldName;
                //    tableField.Width = fieldWidth;
                //    tableField.Filling.Pattern = "0";
                //}

                //D: Projekt speichern
                //US: Save project
                proj.Save();
            }
        }
        catch (ListLabelException LlException)
        {
            //D: Exception abfangen
            //US: Catch Exceptions
            //MessageBox.Show("Information: " + LlException.Message + "\n\nThis information was generated by a List & Label custom exception.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            throw new Exception(LlException.Message);
        }
    }

But it seems to me that this is not how I should use Open in my case, I’m trying to pass the Id of the project to be opened, but I think I must be making a mistake.

Yes, exactly. The Web Report Designer can then be used for editing.

Regarding your code, you should call the GenerateLLProject method before opening the view that contains the Web Report Designer (WRD). And then open the WRD for this newly created project. Or - even better, if I understand you correctly - not open the WRD at all but rather have a view that just contains the Web Report Viewer. You can pass the Id of the project to render e. g. in the WebReportViewer tag. Here’s some code:

Thanks. But see the code above, is this order correct??

ListLabel ll = DefaultSettings.GetListLabelInstance(provideListLabelContext.RepositoryId, null);

    GenerateLLProject(ll);

    provideListLabelContext.NewInstance = ll;

And on the method GenerateLLProject(ll), how can I open the project?

It doesn’t work this way → proj.Open(“repository://{2BB00D79-5124-46D8-BFF1-C8460014DA1D}”, LlDomFileMode.Create, LlDomAccessMode.ReadWrite);

Please, answer here. And the last question is also related to this.

Hello Mr. Jochen Bartlau…

As I wrote, you probably need to move the generation out of the controller method. Also, make sure to assign an instance of your IRepository implementation to the FileRepository member of the ListLabel instance you’re using to create the project.

Once this is done,

proj.Open(“repository://{2BB00D79-5124-46D8-BFF1-C8460014DA1D}”, LlDomFileMode.Create, LlDomAccessMode.ReadWrite);

should work just fine.

Thank you very much for your support.
I have one last question, I would like to use ll-webreportdesigner to create a new project, so I will not pass a defaultProject, however it opens the designer leading to this page:

However, I would like it to automatically create a new project, setting it with the type as ‘List’ for example, although I would like to customize it so that it receives a property from the front-end that indicates which type to use, would it be ‘List’, ‘Label’ or ‘Card’.
I would also like to receive properties from the frontend such as the ‘name’ of the design or project being created.

1 Like

Unfortunately, there is currently no way to intervene at this stage. If you would like to predefine reports, you need to do so beforehand (e.g., in a separate view/page) and pass the predefined report as the default project to the Web Report Designer.

Creating a custom wizard that integrates with the Web Report Designer is an excellent idea, however. If you wish, please feel free to add this as a suggestion at Idea Place - combit Reporting Forum.

1 Like

The idea of creating a custom wizard that integrates with the Web Report Designer is excellent. I will follow your suggestion and add this idea to the Idea Place on the combit Reporting Forum.

Thank you again for your help and guidance.

1 Like

In the meantime, I’m going to ask you one last question, and I thank you for your understanding.

If you remember, the main topic of our conversation was about creating a design from code, in which you said it’s possible using the Object Model (DOM). That said, what I want is to be able to execute these steps via code, I’ve attached images:





So, basically it’s in this code where I should do this, right?
I’d like some pointers or a step by step on how to do this, if possible, I’ve tried a few approaches, but to no avail.

private static void GenerateLLProject(ListLabel ll, Stream projectStream)
{
    try
    {
        string tempFilePath = Path.Combine(Path.GetTempPath(), "tempProject.lst");

        SaveStreamToFile(projectStream, tempFilePath);

        using (ProjectList proj = new ProjectList(ll))
        {
            proj.Open("C:\\Users\\PC\\AppData\\Local\\Temp\\tempProject.lst", LlDomFileMode.Create, LlDomAccessMode.ReadWrite);

            
            proj.Save();

        }

    }

    catch (ListLabelException LlException)
    {
        throw new Exception(LlException.Message);

    }

}

If you’ve atteched your repository as suggested:

You should be able to use the Open and Save methods as expeted. The changes will then be synced to the repository and the designer should use the updated project. Again, this needs to be done before the Web Report Designer is opened and the modified repository item should then be passed as project to open.

I can now open the project, my issue is following the steps to add a table and fields from datasource via code

That should work like in this sample:

Make sure to add the required data source to the ListLabel component if you’re not ignoring syntax errors (which is a parameter of the project’s Open method),

Yes, thank you. I tried to base myself on this example, the big problem is that when I use ObjectReportContainer container = new ObjectReportContainer(proj.Objects);, the layout doesn’t open, i.e. it doesn’t give any error when mounting the layout. But when I open Designer and try to import the file and then open it, it just gives an error. If I remove the ObjectReportContainer container = new ObjectReportContainer(proj.Objects); it no longer gives an error, the problem is that in the example I see that the ObjectReportContainer is essential to be able to move forward.

Can you elaborate on this? Which error are you getting?

Everything is working now, thank you very much for your support!

1 Like