Open frankleib opened 2 years ago
Hi. This functionality is intended to export only the visible data set, since it exports through DOM, it doesn't query database for more data. I suggest to use page size control to increase and decrease the visible data set. In my solutions I use it to export a full data set. You just have to set a high enough page size on the grid so that all of the elements show up. Then you can export them all just as a smaller data set. A user has control over how much data he wants to export by utilizing the page size control.
I have a List of Classitemes generated from a csv from a FTP file sharing with different calcs as Source for the DG, no DB and the List is has a 30_000+ Elements, so I can't show it complet in the Browser, I have to worke with pages, in the other way I get error because the page is to complex/big. It s is a very nice tool, but I thing it s better to do it DG sourcebased instad of DOM, in this way it's would by perfect
That is an interesting suggestion. I will consider adding a different mode of export, "DataSource" mode, where you could provide a method for loading data. This component would in return export all of the data your method would return. Can't promise when exactly this would be implemented, but I hope this month :)
sounds nice, do you have for support a paypal pool or so on for a little donate?
Hi. Sorry for the long delay, had a lot of other work in the way. I have implemented the first draft of the server data source mode. It is released as a prerelease nuget 3.3.0.1-servermode
. Could you please download and test it on your side and give feedback?
To enable the server data source mode, you have to provide 4 additional parameters.
DataSourceMode = true
to enable the mode,
LoadDataAllMethod
of type Func<Task<IEnumerable<T>>>
. This method will be called to retrieve the data set that you want to export.
ReferenceValueFieldNames
of type IEnumerable<string>
. This is the list of property names that are reference values and require fetching references by key on the run from the server or other repository.
HandleReferenceValue
of type Func<string, string<Task<string>>
. This is called when there are some ReferenceValueFieldNames
provided to resolve the reference property value (for example, to retrieve customer name from customer id). There are two arguments passed into the function, first is the property name and second is the property reference value (for example customer id).
The working example would look something like this:
<Radzen.Blazor.GridExportOptions.RadzenGridExportOptions Grid="@grid" CSVButtonStyle="Radzen.ButtonStyle.Info" NotExportableClass="not-exportable" DataSourceMode="true" LoadDataAllMethod="LoadDataAll" ReferenceValueFieldNames="GetReferenceValueFieldNames" HandleReferenceValue="HandleReferenceValue" />
async Task<IEnumerable<T>> LoadDataAll()
{
... data retrieval ...
}
IEnumerable<string> GetReferenceValueFieldNames()
{
return new List<string>(){ "Customer_Id" };
}
async Task<string> HandleReferenceValue(string fieldName, string value)
{
var res = "";
if (fieldName == "Customer_Id")
res = _customers.FirstOrDefault(x => x.Id == value).Name;
//_customers is a list of customer object that has been loaded some time before.
return res;
}
In regards to a donation, I don't actively promote it, however if you want to show appreciation in that way, please feel free to go to my profile and donate. Any donations will in some way be used to improve my open source work.
Hi, I can't see a 3.3.0.1 NuGet package in the manager, sorry, but I don't know a way to test it
Hi. Please check "Include prerelease" checkbox to see the newest nuget package versions.
Thanks, the NuGet install works, but I don't understand how I use it, for my example
`using BOEERP.Common.WebHelper; using BOEERP.SuppliersArticleDataImport; using BOEERP.SuppliersArticleDataImport.Models; using Microsoft.AspNetCore.Components; using Radzen; using Radzen.Blazor;
namespace BOEERP.Pages
{
public partial class ArticleInfoImportSelect
{
[Parameter]
public string? urlparamdata { get; set; }
string pagingSummaryFormat = "Seite {0} von {1} (insgesamt {2} Artikel)";
RadzenDataGrid
void Open(string title, Type type, Dictionary<string, object> parameters, DialogOptions options)
{
}
void Close(dynamic result)
{
}
public void Dispose()
{
// The DialogService is a singleton so it is advisable to unsubscribe.
DialogService.OnOpen -= Open;
DialogService.OnClose -= Close;
}
protected override void OnInitialized()
{
DialogService.OnOpen += Open;
DialogService.OnClose += Close;
}
void ShowNotification(NotificationMessage message)
{
NotificationService.Notify(message);
}
protected override void OnParametersSet()
{
if (fTPProfilDB is null)
{
LoadStartData();
}
if (fTPImportElements is not null && fTPImportElements.Count() > 0)
{
profilExists = true;
}
else
{
profilExists = false;
}
}
//UI events
async Task OnClickStartImport()
{
_ = BusyDialog();
await Task.Run(() => Import());
DialogService.Close();
}
//Function
void LoadStartData()
{
finishLoadingData = false;
urlParameterDic = new URIParameterDic().GetUriParameterDictionary(urlparamdata, "_br_", "_=_")!;
fTPProfilDB = new FTPProfilDB(Convert.ToInt32(urlParameterDic["konto"]));
fTPImportProfil = fTPProfilDB.fTPImportProfil!;
if(fTPImportProfil is not null && fTPImportProfil.Id > 0)
{
fTPImportElements = (new FTPImport(fTPImportProfil.FTPImportParameter)).importElements;
}
if(fTPImportElements is not null && fTPImportElements.Count() > 0)
{
fTPImportElements = fTPImportElements.OrderByDescending(s => s.Identnr);
}
finishLoadingData = true;
}
void Import()
{
FTPUpdateE025 fTPUpdateE025 = new(fTPImportSelectedElements);
if(fTPUpdateE025.Error)
{
ShowNotification(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "Import erfolgte mit Fehlern", Detail = fTPUpdateE025.ErrorTxt, Duration = 99999999 });
}
else
{
ShowNotification(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "Import erfolgreich: ", Detail = "Der Import war erfolgreich", Duration = 99999999 });
}
}
//Grid Export
async Task<IEnumerable<FTPImportElement>> LoadDataAll()
{
}
IEnumerable<string> GetReferenceValueFieldNames()
{
return new List<string>() { "Customer_Id" };
}
async Task<string> HandleReferenceValue(string fieldName, string value)
{
var res = "";
if (fieldName == "Customer_Id")
res = fTPImportElements.FirstOrDefault(x => x.Id == value).Name;
//_customers is a list of customer object that has been loaded some time before.
return res;
}
}
}
@page "/ftpimportselection/{urlparamdata?}" @using BOEERP.SuppliersArticleDataImport.Models @using Radzen @using BOEERP.Common.WebHelper @using Radzen.Blazor.GridExportOptions @using System.Threading;
@inject FTPFilesInDirService filesInDirService @inject NotificationService NotificationService @inject DialogService DialogService @inject TooltipService tooltipService @inject ContextMenuService ContextMenuService
@implements IDisposable
@if(profilExists) {
<div>
<RadzenButton Click=@(args => OnClickStartImport()) Text="Importieren" Icon="check_circle" ButtonStyle="ButtonStyle.Success"/>
<RadzenGridExportOptions Grid="@grid" NotExportableClass="not-exportable" DataSourceMode="true" LoadDataAllMethod="LoadDataAll" ReferenceValueFieldNames="GetReferenceValueFieldNames" HandleReferenceValue="HandleReferenceValue" CsvExport="false" DateTimeFormat="dd.MM.yyyy" ExcelTitle="Excel Export" />
</div>
<hr>
<div>
<RadzenDataGrid AllowFiltering="true" AllowMultiColumnSorting="true" AllowPaging="true" PageSize="20" AllowColumnReorder="false"
PageSizeOptions="@pageSizeOptions" ShowPagingSummary="true" PagingSummaryFormat="@pagingSummaryFormat" PageSizeText="Artikel pro Seite"
OrOperatorText="oder" AndOperatorText="und" ContainsText="enthält" StartsWithText="beginnt mit" EndsWithText="endet mit" DoesNotContainText="enthält nicht" IsNullText="is leer" IsNotNullText="ist nicht leer" ApplyFilterText="anwenden" ClearFilterText="leeren"
EqualsText="gleich" NotEqualsText="ungleich" LessThanText="kleiner als" LessThanOrEqualsText="kleiner gleich" GreaterThanText="größer als" GreaterThanOrEqualsText="größer gleich"
AllowSorting="true" Data="@fTPImportElements" TItem="FTPImportElement" ColumnWidth="200px"
SelectionMode="DataGridSelectionMode.Multiple" @bind-Value=@fTPImportSelectedElements>
<Columns>
<RadzenDataGridColumn TItem="FTPImportElement" Width="20px" Sortable="false" Filterable="false" CssClass="exclude-from-radzen-export" HeaderCssClass="exclude-from-radzen-export">
<HeaderTemplate>
<RadzenCheckBox TriState="false" TValue="bool" Value="@(fTPImportElements.Any(i => fTPImportSelectedElements != null && fTPImportSelectedElements.Contains(i)))"
Change="@(args => fTPImportSelectedElements = args ? fTPImportElements.ToList() : null)" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TriState="false" Value="@(fTPImportSelectedElements != null && fTPImportSelectedElements.Contains(data))" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Lieferant" Title="Lieferant" Width="0px" CssClass="radzen-blazor-gridexportoptions-column-number"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Identnr" Title="Artikelnummer" Width="70px" CssClass="radzen-blazor-gridexportoptions-column-number" />
<RadzenDataGridColumn TItem="FTPImportElement" Property="Bezeichnung" Title="Bezeichnung" Width="300px" CssClass="radzen-blazor-gridexportoptions-column-number"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Menge_ab" Title="Ab-Menge" Width="60px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Ekpreis" Title="EK-Preis" Width="60px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Menge_verf" Title="verf.Menge" Width="60px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Liefterm" Title="Liefertermin" FormatString="{0:d}" Width="70px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="anp_ve_lief" Title="VE" Width="60px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="anp_palmenge" Title="PAL" Width="60px" TextAlign="TextAlign.Right"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="EAN" Title="EAN" Width="100px" CssClass="radzen-blazor-gridexportoptions-column-number"/>
<RadzenDataGridColumn TItem="FTPImportElement" Property="Kdidentnr" Title="Artikel-Lieferant" CssClass="radzen-blazor-gridexportoptions-column-number"/>
</Columns>
</RadzenDataGrid>
</div>
} else { @if(finishLoadingData == false && fTPImportElements is null) {
}
else
{
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<h2 style="text-align:center; color:red">keine Daten gefunden</h2>
}
}
@code { async Task BusyDialog() { await DialogService.OpenAsync("", ds => @
</div>, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false });
}
} `
with
IEnumerable<string> GetReferenceValueFieldNames() { return new List<string>() { "Lieferant", "Identnr", "Bezeichnung", "Menge_ab", "Ekpreis", "Menge_verf", "Liefterm", "anp_ve_lief", "anp_palmenge", "EAN", "Kdidentnr" }; }
and
<Radzen.Blazor.GridExportOptions.RadzenGridExportOptions Grid="@grid" CSVButtonStyle="Radzen.ButtonStyle.Info" NotExportableClass="not-exportable" DataSourceMode="true" LoadDataAllMethod="LoadDataAll" ReferenceValueFieldNames="GetReferenceValueFieldNames" HandleReferenceValue="HandleReferenceValue" />
I get a "Severity Code Description Project File Line Suppression State
Error (active) CS1503 Argument 14: cannot convert from 'method group' to 'IEnumerable
"
Hi,
I see the problem now. I have made a mistake in my sample. "ReferenceValueFieldNames " has to be an IEnumerable, not a function. You can try replacing yours with: ReferenceValueFieldNames="@(() => GetReferenceValueFieldNames())".
My apologies for the mistake.
=>Severity Code Description Project File Line Suppression State
Error (active) CS1660 Cannot convert lambda expression to type 'IEnumerable
:-)
Okay, lets try again. use "@GetReferenceValueFieldNames()" instead of "@(() => GetReferenceValueFieldNames())".
this is working, thank you!
but it will freeze yet.
public class FTPImportElement { public int Id { get; set; } public int Lieferant { get; set; } public string? Kdidentnr { get; set; } public string? EAN { get; set; } public string? Identnr { get; set; } public string? Bezeichnung { get; set; } public decimal Menge_ab { get; set; } = 0; public decimal Ekpreis { get; set; } public decimal? Menge_verf { get; set; } public DateTime? Liefterm { get; set; } public decimal? anp_ve_lief { get; set; } public decimal? anp_palmenge { get; set; }
private string _errorContent = "";
public string ErrorContent
{
get { return _errorContent; }
set { _errorContent += value; }
}
public bool selected { get; set; }
public bool Error { get; set; } = false;
public bool setIdentnr()
{
try
{
using (SqlConnection connection = new SqlConnection(B7DB.b7MSQLConnetionString))
{
connection.Open();
int count = 0;
SqlCommand cmd = new SqlCommand("select identnr from g040 where ean=" + EAN, connection);
SqlDataReader sdr = cmd.ExecuteReader();
if (sdr.HasRows)
{
while (sdr.Read())
{
if (count > 0)
{
throw new Exception("Mehr als ein Ergebnis bei der identnr-Suche für g030.ean=" + EAN);
}
Identnr = sdr.GetString(0);
count++;
}
}
else
{
Identnr = "";
}
}
}
catch (Exception e)
{
Error = true;
ErrorContent = " // FTPProfilDB getFTPImportProfil(int _Lieferant) select: " + e.ToString();
}
return true;
}
}
IEnumerable
void LoadStartData() { finishLoadingData = false;
urlParameterDic = new URIParameterDic().GetUriParameterDictionary(urlparamdata, "_br_", "_=_")!;
fTPProfilDB = new FTPProfilDB(Convert.ToInt32(urlParameterDic["konto"]));
fTPImportProfil = fTPProfilDB.fTPImportProfil!;
if(fTPImportProfil is not null && fTPImportProfil.Id > 0)
{
fTPImportElements = (new FTPImport(fTPImportProfil.FTPImportParameter)).importElements;
}
if(fTPImportElements is not null && fTPImportElements.Count() > 0)
{
fTPImportElements = fTPImportElements.OrderByDescending(s => s.Identnr);
}
finishLoadingData = true;
}
async Task<IEnumerable
IEnumerable<string> GetReferenceValueFieldNames()
{
return new List<string>() { "Lieferant", "Identnr", "Bezeichnung", "Menge_ab", "Ekpreis", "Menge_verf", "Liefterm", "anp_ve_lief", "anp_palmenge", "EAN", "Kdidentnr" };
}
async Task<string> HandleReferenceValue(string fieldName, string value)
{
var res = "";
if (fieldName == "Lieferant")
{
res = fTPImportElements.FirstOrDefault(x => x.Lieferant.ToString() == value).ToString();
}
return res;
}
Are there a lot of rows? Can you specify when and how it freezes?
30_000 rows
I have a breakpoint in all 3 methods and it freeze after async Task<IEnumerable
can you please upload a complete example for use, because it's possible, that it is my mistake
[2022-07-09T21:59:26.664Z] Error: System.NullReferenceException: Object reference not set to an instance of an object.
at Radzen.Blazor.GridExportOptions.RadzenGridExportOptions1.GetVisibleColumns() at Radzen.Blazor.GridExportOptions.RadzenGridExportOptions
1.ExportToExcel()
at System.Threading.Tasks.Task.<>c.
Hi. My deepest apologies for a late answer. I have been looking into this and I think currently exporting large data is not possible, because there is a serialization limit while passing data to JS function via JS interop. In regards to the last error "Null reference" it is hard to debug what can be "null" there since I don't see a complete example. Can you provide one? Or you can import this project manually (not nuget package) and debug yourself. That would be much appreciated.
If you use Paging in a Datagrid you get only the actual page in Excel, not the complet Datasets