Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1.3K
Visualizações
Problemas de RDLC en monitores con mayor escala recomendada

Estoy en .net framework 4.8 en mi aplicación WPF y tengo dos usos en RDLC. El primero es un ReportViewer completamente obtenido que usa un DataTable de postgres, el segundo es solo un Informe local con una pequeña cantidad de parámetros representados como EMF e impresos directamente con el uso de la impresora predeterminada.

Ambos tienen lo que parecería ser un problema de renderizado, pero solo en monitores que tienen una escala recomendada (RS)> 100%. El resultado es aplastar las letras verticalmente y agregar algo de espacio adicional en el medio (puedo proporcionar muestras tan pronto como vuelva a tener acceso a la máquina del cliente). Si solo aumento la escala en mi monitor 100% RS, todo se imprime bien. Si reemplazo el monitor >100% RS con uno de 1080p 100% RS, nuevamente, todo se imprime bien. Las impresiones en máquinas con monitores con >100 % RS siempre salen desordenadas, independientemente de la escala que configuré en Windows. Los problemas se pueden reproducir rápidamente con solo la vista 'Diseño de impresión' en ReportViewer, exportar a PDF produce los mismos resultados.

Como tengo ReportViewer y una impresión directa de LocalReport, pude probar varios enfoques diferentes:

  • Hacer que la aplicación sea DPIAware/no consciente/verdadera/PM, etc. (también se incluyen cambios en el manifiesto, App.config y App.xaml)
  • Poner ReportViewer en ViewBox
  • Uso de DpiX/Y y PrintDpiX/Y en DeviceInfo
  • ScaleTransform y DrawImageUnscaled en la devolución de llamada de PrintPage con y sin los cambios de DeviceInfo
  • innumerables opciones de impresora en Windows

Las máquinas cliente se ejecutan en la última versión de Windows 10 o cerca de la última y, de lo contrario, están bastante vacías.

¿Te suena de algo? ¿Alguna idea para una posible solución?

Me encantaría usar RDLC en mi aplicación, por la simplicidad de desarrollo y uso, pero esos problemas son realmente un problema para la tecnología.

Código

Sin impresión de vista previa

Se utiliza para imprimir un solo documento directamente sin vista previa de los parámetros.

 class CytologiaPrinter : IDisposable { private static readonly ILog log = LogManager.GetLogger(typeof(CytologiaPrinter)); private int m_currentPageIndex; private IList<Stream> m_streams; private int WizytaID; private CytologiaAnkieta Cytologia; public CytologiaPrinter(int wizytaID) { WizytaID = wizytaID; } public CytologiaPrinter(CytologiaAnkieta cytologia) { Cytologia = cytologia; } public void Print() { try { CytologiaAnkieta cytologia; if (Cytologia == null) { cytologia = DBCommunication.fetchCytologia(WizytaID); } else { cytologia = Cytologia; } if (cytologia != null && cytologia.AnkietaNumer != null && cytologia.AnkietaNumer.Length > 0) { LocalReport report = new LocalReport(); var cytologie = new List<CytologiaAnkieta>(); cytologie.Add(cytologia); ReportDataSource reportDataSource = new ReportDataSource("DataSet1", cytologie); report.DataSources.Add(reportDataSource); report.ReportEmbeddedResource = "Suplement.CytologiaAnkieta.rdlc"; var parameters = new List<ReportParameter>(); //parameters.Add(...); //setting all parameters omitted for demo report.SetParameters(parameters); m_currentPageIndex = 0; Print(cytologia); } } catch (Exception ex) { log.Error("Error (" + ex.Message + "), stack:" + ex.StackTrace); } } private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { Stream stream = new MemoryStream(); m_streams.Add(stream); return stream; } private void Export(LocalReport report) { string deviceInfo = @"<DeviceInfo> <OutputFormat>EMF</OutputFormat> <PageWidth>29.7cm</PageWidth> <PageHeight>21cm</PageHeight> <MarginTop>1cm</MarginTop> <MarginLeft>1cm</MarginLeft> <MarginRight>1cm</MarginRight> <MarginBottom>1cm</MarginBottom> </DeviceInfo>"; //printing in landscape Warning[] warnings; m_streams = new List<Stream>(); report.Render("Image", deviceInfo, CreateStream, out warnings); if (warnings != null && warnings.Length > 0) { foreach (var warn in warnings) { log.Warn("Cytologia printing issues: " + warn.Message); } } foreach (Stream stream in m_streams) stream.Position = 0; } private void PrintPage(object sender, PrintPageEventArgs ev) { Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); Rectangle adjustedRect = new Rectangle( ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX, ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY, ev.PageBounds.Width, ev.PageBounds.Height); ev.Graphics.FillRectangle(Brushes.White, adjustedRect); ev.Graphics.DrawImage(pageImage, adjustedRect); m_currentPageIndex++; ev.HasMorePages = m_currentPageIndex < m_streams.Count; } private void Print(CytologiaAnkieta cytologia) { if (m_streams == null || m_streams.Count == 0) throw new Exception("Error: no stream to print."); PrintDocument printDoc = new PrintDocument(); printDoc.DefaultPageSettings.Landscape = true; if (!printDoc.PrinterSettings.IsValid) { throw new Exception("Error: cannot find the default printer."); } else { printDoc.PrintPage += new PrintPageEventHandler(PrintPage); m_currentPageIndex = 0; printDoc.Print(); } } public void Dispose() { if (m_streams != null) { foreach (Stream stream in m_streams) stream.Close(); m_streams = null; } } }

Vista previa de WinForms

Xaml

 xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms" ... <WindowsFormsHost DockPanel.Dock="Bottom" Margin="0 0 0 0" > <rv:ReportViewer x:Name="RVDemo"/> </WindowsFormsHost>

Parte del código C#

 private void RaportGenerate_Click(object sender, RoutedEventArgs e) { RVDemo.Reset(); ReportDataSource reportDataSource = new ReportDataSource("Ankiety", DBCommunication.fetchCytologiaAnkietyReport(...)); RVDemo.LocalReport.DataSources.Add(reportDataSource); RVDemo.LocalReport.ReportEmbeddedResource = "Suplement.Cytologie.rdlc"; var parameters = new List<ReportParameter>(); //parameters.Add(...); // omitted for demo RVDemo.LocalReport.SetParameters(parameters); RVDemo.RefreshReport(); }
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

El problema es bien conocido, también afecta el rendimiento. La razón es simple:

RDLC fue creado para entregar informes simples como recibo o factura. cualquier cosa más que eso te va a causar muchos problemas y muchos dolores de cabeza.

Hay una solución simple que ofrece el soporte técnico de Microsoft en la web:

  • Cambiar la configuración de DPI del sistema
  • Cambiar la fuente en el informe
  • Haga que el visor de informes se adapte a una resolución más alta automáticamente.

Pero todos ellos simplemente ignoran el simple hecho de que RDLC nunca fue diseñado para grandes informes o resoluciones más altas. Solo para documentos como facturas o recibos que son modestos y con una pequeña cantidad de detalles para abordar

over 4 years ago · Santiago Trujillo Relatório

0

Si no hay soluciones disponibles para el problema de escalado de RDLC en la aplicación WPF.

Una posible solución sería migrar la parte de representación de archivos a la versión web de RDLC, que ignoraría la pantalla DPI (hasta donde yo sé).

Necesitará recursos adicionales para desarrollar esto.

Pero unas pocas funciones genéricas serían suficientes, en la mayoría de los casos.

Entonces sus informes deberían poder renderizarse con escalado consistente.


(Es posible que no necesite una biblioteca de proyectos adicional para ReportViewer.WebForms si la versión de la biblioteca Microsoft.ReportViewer.Common puede ser utilizada tanto por WebForms como por WinForms ReportViewer).

Aquí está la posible solución:

1) Agregue un proyecto de biblioteca a su solución WPF

La solución debe usar .NET Framework 4+. Se vería algo como esto.

ingrese la descripción de la imagen aquí

2) Descargue la versión WebForm de RDLC a la nueva biblioteca a través de NuGet

Busque Microsoft.ReportViewer.WebForms de Microsoft.

Se instalará la versión correcta de Microsoft.ReportViewer.Common como dependencia.

ingrese la descripción de la imagen aquí

3) Cree el código para renderizar a través de la versión web de RDLC

Cree una clase estática para que la use el proyecto WDF, esta es una muestra muy simple para que pruebe si funciona, antes de continuar.

Copie esta clase en el proyecto "RLDCRendering":

 using Microsoft.Reporting.WebForms; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RDLCRendering { public class RDLCRender { public static byte[] RenderReport(String reportPath, DataTable data) { Microsoft.Reporting.WebForms.ReportDataSource rdc1 = new Microsoft.Reporting.WebForms.ReportDataSource("DataSet1", data); Microsoft.Reporting.WebForms.ReportViewer v1 = new Microsoft.Reporting.WebForms.ReportViewer(); v1.LocalReport.DataSources.Clear(); v1.LocalReport.ReportPath = reportPath; v1.LocalReport.DataSources.Add(rdc1); return v1.LocalReport.Render(format: "PDF", deviceInfo: ""); } } }

El proyecto quedaría así:

ingrese la descripción de la imagen aquí

4) Ocultar el botón de impresión del informe de la versión WPF

Oculte el botón Imprimir/Guardar con este código de ejemplo para que los usuarios no utilicen el método de representación defectuoso

 ReportViewer.ShowPrintButton = false; ReportViewer.ShowExportButton = false;

Agregue un botón de impresión en su página WDF, cómo lo hace depende de usted.

El resultado final es algo como esto: ingrese la descripción de la imagen aquí

Agregue una devolución de llamada cuando se haga clic en el botón, luego proporcione toda la fuente de datos necesaria, la ruta del informe, la ruta de salida a la biblioteca que creamos.

El siguiente es un código de muestra para usted:

 string connString = "Server=someIP;Database=catalogName;User Id=uid;Password=pwd"; SqlConnection sqlConn = new SqlConnection(connString); SqlDataAdapter sqlDA = new SqlDataAdapter("select top 100 * from samplesData", sqlConn); DataTable dt= new DataTable(); sqlDA.Fill(dt); //Important Byte[] bytes = RDLCRendering.RDLCRender.RenderReport(@"the path to the report teamplate\Report1.rdlc", dt); using (FileStream stream = new FileStream(@"C:\test\test.pdf", FileMode.Create)) { stream.Write(bytes, 0, bytes.Length); }

5) Validar

Puede cambiar la ruta de salida según lo necesite. Cuando se hace clic en el botón, se debe procesar y guardar un archivo PDF en la ubicación que especificó. En mi ejemplo, está en C:\test\test.pdf.

Si esta solución funciona para usted, puede continuar agregando parámetros, etc. a la/otra función de representación byte[] RenderReport .

Luego maneje el archivo de bytes devuelto enviándolo a la impresora o guárdelo en alguna carpeta local y ábralo con otras aplicaciones.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda