具有更高推荐缩放比例的监视器上的RDLC问题
c#
我在我的 WPF 应用程序中使用 .net framework 4.8,我在 RDLC 上有两种用法。第一个是完全提取的 ReportViewer,它使用来自 postgres 的数据表,第二个只是一个 LocalReport,其中有少量参数呈现为 EMF,并使用默认打印机直接打印。
它们都似乎存在渲染问题,但只是在建议缩放 (RS) > 100% 的显示器上。结果是垂直压缩字母并在它们之间添加一些额外的空间(我可以在再次访问客户端计算机后立即提供示例)。如果我只是在我的 100% RS 显示器上增加缩放比例,那么一切都打印得很好。如果我用 1080p 100% RS 显示器替换 >100% RS 显示器,同样,一切都可以正常打印。与我在 Windows 中设置的缩放比例无关,在显示器上的打印输出 > 100% RS 出来总是一团糟。只需使用 ReportViewer 中的“打印布局”视图即可快速重现问题,导出为 PDF 会产生相同的结果。
由于我有 ReportViewer 和 LocalReport 的直接打印输出,我可以尝试几种不同的方法:
- 使应用程序 DPIAware/notaware/true/PM 等(还包括清单、App.config 和 App.xaml 更改)
- 将 ReportViewer 放入 ViewBox
- 在 DeviceInfo 上使用 DpiX/Y 和 PrintDpiX/Y
- ScaleTransform 和 DrawImageUnscaled 在 PrintPage 回调中使用和不使用 DeviceInfo 更改
- Windows 中的无数打印机选项
客户端机器运行在最新的 Windows 10 或接近最新的 Windows 10 上,否则相当空。
它敲响了钟声吗?任何潜在修复的想法?
我很想在我的应用程序中使用 RDLC,为了开发和使用的简单性,但这些问题对于该技术来说确实是不可行的。
代码
没有预览打印输出
用于直接打印单个文档,无需通过参数进行预览。
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;
}
}
}
预览 WinForms
xml
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>
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();
}