Skip to main content
Announcements
Defect acknowledgement with Nprinting Engine May 2022 SR2, please READ HERE
cancel
Showing results for 
Search instead for 
Did you mean: 
colinhancox_wp
Contributor III
Contributor III

On-demand report generation to network folder

I've been asked to come up with a solution to the following request.  The users want to be able to click on a button in a QlikView report and generate a report using NPrinting, that is saved to a network location rather than downloading locally.  They need to do this at random times and the report needs to use the selections they have made.  Essentially on-demand reporting, but to a network location.  I have considered having a button that exports their selections as a text file and then somehow picking that up and called the NPrinting API, passing the selections as a filter.

Has anyone attempted anything like this or have any suggestions?

If it is not possible in QlikView, Qlik Sense would also be an option, although most of the users have QlikView licences only.

Thanks.

Labels (2)
21 Replies
JonnyPoole
Employee
Employee

The name of the outputted file was Excel.xlsx so I think you are good there. Silly name I know. 

colinhancox_wp
Contributor III
Contributor III
Author

The solution I developed for this uses a QlikView macro to export the user selections to a csv file.  The files are username and datetime stamped, so it allows for multiple concurrent users.  Then I have a Powershell script that runs and uses the NPrinting API to loop through the files, update a filter and run the publish task that uses that filter.  We use Control-M to watch for the generation of the selections file, move the file to another folder and then run the script.  The tricky part of the script was creating the JSON body for the filter, but that works now, for single or multiple selections.  I have a parameters file that stores the NPrinting server, folder, task ID, connection ID and filter ID, so the same script can be used for different QlikView apps.  So far it has been pretty robust and held up under testing.

The selections file (Selections-U123456-20240416103449.csv) look like this:

name,type,value
%Period,text,DTD
Currency,text,AUD
Reporting Group,text,Profit & Loss
Region,text,East;North

The script caters for multiple selections in a field, semicolon separated.

This is the parameters file:

server,selectionsfolder,appId,connectionId,filterId,filterName,taskId
https://nprintingserver:4993,\\Apps\NPrintingSelections,c6a327cf-ec08-4374-99cf-e734fadg87be,73b63e50-cfa0-4c7c-8708-28584ce6935c,f1g1f5b1-79fa-4d2b-8724-b609f0daf12e,Generic,50089a1c-a6d4-4352-8623-fav23a544ca9

This is the Powershell script:

# Load variables from CSV file

$variables = Import-Csv -Path ".\NPParameters.txt"

$server = $variables.server

$appId = $variables.appId

$connectionId = $variables.connectionId

$filterId = $variables.filterId

$filterName = $variables.filterName

$taskId = $variables.taskId

$directory = $variables.selectionsfolder




# Set TLS to minimum 1.1 for NPrinting Feb 2018 (using 1.2 in this example)

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12




# Authenticate and get cookie

$url = "$server/api/v1/login/ntlm"

Invoke-RestMethod -UseDefaultCredentials -Uri $url -Method Get -Headers $hdrs -SessionVariable websession

$cookies = $websession.Cookies.GetCookies($url)

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

$session.Cookies.Add($cookies)




# Extract XSRF token from cookie

$xsrf_token = $($cookies | Where-Object {$_.Name -eq "NPWEBCONSOLE_XSRF-TOKEN"}).Value




$hdrs = @{}

$hdrs.Add("X-XSRF-token", $xsrf_token)




# Get all the files in the directory

$files = Get-ChildItem -Path $directory -File




# Loop through each file in the directory

foreach ($file in $files) {

    # Read data from CSV file

    $data = Import-Csv -Path $file.FullName




    # Convert filter fields to JSON

    $fields = @()




    # Group the data by name

    $groupedData = $data | Group-Object -Property name




    # Loop through each group in the grouped data

    foreach ($group in $groupedData) {

        # Create an empty array to hold the values

        $values = @()




        # Loop through each row in the group

        foreach ($row in $group.Group) {

            # Split the values into an array

            $valueArray = $row.value -split ";"




            # Loop through each value

            foreach ($value in $valueArray) {

                # Create a new PSObject and add properties to it

                $valueObject = New-Object PSObject

                $valueObject | Add-Member -Type NoteProperty -Name "value" -Value $value

                $valueObject | Add-Member -Type NoteProperty -Name "type" -Value $row.type




                # Add the new object to the values array

                $values += $valueObject

            }

        }




        # Create a new PSObject and add properties to it

        $field = New-Object PSObject

        $field | Add-Member -Type NoteProperty -Name "connectionId" -Value $connectionId

        $field | Add-Member -Type NoteProperty -Name "name" -Value $group.Name

        $field | Add-Member -Type NoteProperty -Name "values" -Value $values




        # Add the new object to the fields array

        $fields += $field

    }




    $updatedBody = @{

        enabled = $true

        name = $filterName

        appId = $appId

        fields = $fields

    } | ConvertTo-Json -Depth 4




    $url = "$server/api/v1/filters/$($filterId)"

    try {

        $filterUpdateResponse = Invoke-RestMethod -WebSession $session -Uri $url -Method Put -ContentType 'application/json' -Headers $hdrs -Body $updatedBody

    } catch {

        Write-Output "Filter update API returned an error. The file will not be deleted."

        continue

    }




Start-Sleep -Seconds 5




    # Run a publish task

    $url = "$server/api/v1/tasks/$taskId/executions"

    try {

        $taskExecutionResponse = Invoke-RestMethod -WebSession $session -Uri $url -Method Post -Headers $hdrs

    } catch {

        Write-Output "Task execution API returned an error. The file will not be deleted."

        continue

    }




    # If no errors, delete the file

    Remove-Item -Path $file.FullName

}