作为笔记记着,以免以后再到处找资料

1. 在不预览的情况下导出文件

先看一个方法说明,想知道ReportViewer支持导出哪些文件类型,在Render方法说明中就有描述

//
// Summary:
// Processes the report and renders it in the specified format using a stream
// provided by a callback function.
//
// Parameters:
// format:
// The format in which to render the report. This argument maps to a rendering
// extension. Supported formats include Excel, PDF, Word, and Image. To access
// the list of available rendering extensions, use the Microsoft.Reporting.WinForms.LocalReport.ListRenderingExtensions()
// method.
//
// deviceInfo:
// An XML string that contains the device-specific content that is required
// by the rendering extension specified in the format parameter. For more information
// about device information settings for specific output formats, see fe718939-7efe-4c7f-87cb-5f5b09caeff4
// Device Information Settings in SQL Server Books Online.
//
// createStream:
// A Microsoft.Reporting.WinForms.CreateStreamCallback delegate function that
// will be used to provide a System.IO.Stream object for rendering.
//
// warnings:
// [out] An array of Microsoft.Reporting.WinForms.Warning objects that describes
// any warnings that occurred during report processing and rendering.
public void Render(string format, string deviceInfo, CreateStreamCallback createStream, out Warning[] warnings);

调用方法Microsoft.Reporting.WinForms.LocalReport.ListRenderingExtensions()就知道了,如果要把支持导出的文件类型列表显示出来,这个方法就是必须的,但是我没试过。

下面的代码主要是参数msdn的例子:https://msdn.microsoft.com/zh-cn/library/ms252091(v=vs.110).aspx

测试例子时,没用他的数据源

抄下代码运行,发现没有像他说的那样导出文件,然后看了下源码,发现他只把文件写进MemoryStream对象,并没看到将其输出到文件的代码,于是补充了点代码,把内存里的

输出到文件中,然后定义了个ExportFileType枚举,又添加了一个ExportToFile方法,其他代码与示例相同

打印的代码我不关心,所以没理他

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.IO;
using System.Data;
using Microsoft.Reporting.WinForms;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.Drawing;
namespace PrintLocalReport
{
public enum ExportFileType
{
PDF
}
public class ReportViewerPrinter:IDisposable
{
private int m_currentPageIndex = ;
private IList<Stream> m_streams;

   private Stream CreateStream(string name, string fileNameExtension, Encoding encoding,
string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
} public void ExportToFile(LocalReport report,string targetPath, ExportFileType fileType)
{
Export(report, targetPath, fileType);
} private void Export(LocalReport report, string targetPath, ExportFileType fileType)
{
string deviceInfo =
@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
</DeviceInfo>";
       //根据我的测试,这里的参数会覆盖rdlc中定义的参数,所以我尝试删除了,发现删除了行为是可预期的,是正确的
       //如果需要,这里可以实现定制化了
//<PageWidth>8.5in</PageWidth>
//<PageHeight>11in</PageHeight>
//<MarginTop>0.25in</MarginTop>
//<MarginLeft>0.25in</MarginLeft>
//<MarginRight>0.25in</MarginRight>
//<MarginBottom>0.25in</MarginBottom> Warning[] warnings;
m_streams = new List<Stream>();
report.Render(fileType.ToString(), deviceInfo, CreateStream,
out warnings);
int bufferLength = ;
byte[] buffer = new byte[bufferLength];
using (FileStream fs = new FileStream(targetPath, FileMode.CreateNew, FileAccess.Write))
{
foreach (Stream stream in m_streams)
{
stream.Position = ;
MemoryStream ms = stream as MemoryStream;
int readLength = ;
while (true)
{
readLength = ms.Read(buffer, , bufferLength);
if (readLength == ) break;
fs.Write(buffer, , readLength);
}
}
}
} 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.Wheat, adjustedRect);
ev.Graphics.DrawImage(pageImage, adjustedRect);
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
} private void Print()
{
if (m_streams == null || m_streams.Count == )
{
throw new Exception("Error:no stream to print");
}
PrintDocument printDoc = new PrintDocument();
if (!printDoc.PrinterSettings.IsValid)
{
throw new Exception("Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = ;
printDoc.Print();
}
} public void Dispose()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
{
stream.Close();
}
m_streams = null;
}
}
}
}

调用代码如下

 static void Main(string[] args)
{ LocalReport report = new LocalReport();
report.ReportPath = @"..\..\report.rdlc";
        //这个tablename要和rdlc指定的数据源名字一致,有多少个数据源挨着挨着添加
report.DataSources.Add(new ReportDataSource("tablename", LoadSalesData()));
        //这里是定义的参数,也挨着挨着添加
IList<ReportParameter> list = new List<ReportParameter>()
{
new ReportParameter("paramName","ParamVale")
};
report.SetParameters(list.ToArray());
try
{
new ReportViewerPrinter().ExportToFile(report, "test.pdf", ExportFileType.PDF);
}
catch (Exception ex)
{ } }

2. 后台导出的代码很简单,主要纠结的地方是在绘制报表的时候

主要是两个问题:

1. 导出到pdf文件后,本来是一页的内容,他纵向劈开,在pdf中分成两页显示了

2.把导出的pdf文件拿去打印,在打印的时候最后一页除了页眉页脚,中间区域是空白的,而pdf中没有这一页(真他妈奇怪)

这两个问题的原因都是报表的尺寸问题,不超宽,他就不会纵向劈开,不超高,他就不会有空白页,我设置如下解决了这两个问题

我的报表设置的Paper size是 A4 21cm 29.7cm ,Margins 都为0 (右键报表设计界面的黑色区域(也就是非报表绘制区域),选择Report Properties 属性)

鼠标左键点击报表绘制区域,打开Properties窗口,属性窗口中也有一个Size属性,这个是报表绘制的宽度

这里的宽度和高度加上Paper size的Margins值 要小于等于Paper size属性的高度宽度

我的设置是Width:21cm,Height:10cm

即时上面设置没问题,如果打印机的设置有问题,打印的最终效果也会有差异,但是我不需要打印,所以没纠结他。

3.推荐个工具,做过ui的可能或者基本都知道,FSCapture,很好用,美工的mark图出的不好时,要做出1:1的ui,就得靠自己了,这次做报表也多亏他。1:1真的很烦。

部署:

记录一下部署遇到的问题,其实就是依赖的动态库没弄全

官方部署方案:https://msdn.microsoft.com/zh-cn/library/ms251723.aspx

里面说:运行 ReportViewer.exe 时,以下文件安装在部署计算机上的全局程序集缓存文件夹中

  • Microsoft.ReportViewer.Common.dll

  • Microsoft.ReportViewer.ProcessingObjectModel.dll

  • Microsoft.ReportViewer.WebForms.dll

  • Microsoft.ReportViewer.WinForms.dll

  • Microsoft.ReportViewer.DataVisualization.dll

这个说明上面的库是ReportViewer的依赖项,他说了会部署在GAC中,那就从GAC中把他拷贝出来,GAC中拷贝只能使用shell命令

如果有VS开发环境,默认安装的话,上面的库就已经打到GAC中了,不是的话就得安装ReportViewer.exe

如果不是开发环境,下面安装官方说的ReportViewer.exe,安装主要是为了提取动态库

ReportViewer.exe 下载地址提供一个:https://www.microsoft.com/en-us/download/details.aspx?id=35747

安装他的时候,要是没有system clr types for sql server 2012,会无法安装,真他的操蛋,说明ReportViewer对SqlServer还有依赖

于是找,链接来了:https://www.microsoft.com/en-us/download/details.aspx?id=29065

但是我特么的下载的是一个txt文档,没鸟他,我直接去在我的开发电脑的GAC里面找Sql Server相关的库,把名字带SqlServer全拷贝出来,和上面的动态库一起,打包,放到一个没环境的电脑上,成功了运行了,然后一个一个试试,最后发现有Misrosoft.SqlServer.Types.dll就能导出成功,

下一步就是资源包,官方文档提到了:

ReportViewer 控件本地化为十种 Visual Studio 语言:简体中文、繁体中文、法语、德语、意大利语、日语、朝鲜语、葡萄牙语(巴西)、俄语和西班牙语。

因为程序是全球提供,要求统一为英语,娘的,为毛没有英语包,这不科学,难道默认就是英语,这也不科学(本地化这块一点不熟悉,才接触),不过由于后台导出,没有窗口,除了表格图片,其他全是报

表数据,所以有不有语言包也无所谓

运行 ReportViewer.exe 时,以下文件安装在部署计算机上的全局程序集缓存文件夹中

ReportViewer 不预览,直接导出 PDF文件的更多相关文章

  1. WPF打印、预览、导出PDF

    本人很懒,已找到可使用样例 例:   http://www.cnblogs.com/guogangj/archive/2013/02/27/2934733.html

  2. 史上最全的springboot导出pdf文件

    最近项目有一个导出报表文件的需求,我脑中闪过第一念头就是导出pdf(产品经理没有硬性规定导出excel还是pdf文件),于是赶紧上网查看相关的资料,直到踩了无数的坑把功能做出来了才知道其实导出exce ...

  3. Lodop如何设置预览后导出带背景的图,打印不带背景图

    Lodop中的ADD_PRINT_SETUP_BKIMG,可以加载上背景图,该背景图在预览的时候可以显示也可以不显示,打印可以打印出来也可以不打印出来.一般套打,都是不打印背景图的,比如一些快递的快递 ...

  4. .Net导出pdf文件,C#实现pdf导出

    最近碰见个需求需要实现导出pdf文件,上网查了下代码资料总结了以下代码.可以成功的实现导出pdf文件. 在编码前需要在网上下载个itextsharp.dll,此程序集是必备的.楼主下载的是5.0版本, ...

  5. 利用ITextSharp导出PDF文件

    最近项目中需要到处PDF文件,最后上网搜索了一下,发现ITextSharp比较好用,所以做了一个例子: public string ExportPDF() { //ITextSharp Usage / ...

  6. 纯前端导出pdf文件

    纯前端js导出pdf,已经用于生产环境. 工具: 1.html2canvas,一种让html转换为图片的工具. 2.pdfmake或者jspdf ,一种生成.编辑pdf,并且导出pdf的工具. pdf ...

  7. .Net导出pdf文件,C#实现pdf导出 转载 http://www.cnblogs.com/hmYao/p/5842958.html

    导出pdf文件. 在编码前需要在网上下载个itextsharp.dll,此程序集是必备的.楼主下载的是5.0版本,之前下了个5.4的似乎不好用. 下载之后直接添加引用. <%@ Page Lan ...

  8. asp.net2.0导出pdf文件完美解决方案【转载】

    asp.net2.0导出pdf文件完美解决方案 作者:清清月儿 PDF简介:PDF(Portable Document Format)文件格式是Adobe公司开发的电子文件格式.这种文件格式与操作系统 ...

  9. C# 利用ITextSharp导出PDF文件

    最近项目中需要导出PDF文件,最后上网搜索了一下,发现ITextSharp比较好用,所以做了一个例子: public string ExportPDF() { //ITextSharp Usage / ...

  10. 在线预览word、excel文件

    直接使用微软提供的在线预览服务. 免费 文件必须为网可访问地址,因为微软的服务器需要访问该文件

随机推荐

  1. 关于Java static 的学习心得

    static,大家都很熟悉.但是要说真的懂,那就很少了.(当然我也不是很懂,但不妨碍学习吗.) 首先,我认为static修饰的成员就是属于类本身的成员.如果你加了一个static修饰符,好吧,那就相当 ...

  2. autolayout

    autolayout.因为之前都是用frame,用代码来做,并且在布局时也很少用storyboard和xib.使得我再这方便经验很欠缺,想用,但是又怕用不好,出现各种意想不到的bug.但是又忽然想到, ...

  3. Selenium自动化测试框架介绍

    Selenium自动化测试框架介绍 1.测试架构作用 a.可维护性 b.提高编写脚本效率 c.提高脚本的可读性 2.框架的几大要素: Driver管理,脚本,数据,元素对象,LOG,报告,运行机制,失 ...

  4. Python: 列表的基本用法

    列表是可变的,可以改变的序列,它能够保存任何数据类型. >>> list = []        #定义一个空列表>>> list.append(1)        ...

  5. SQL Server 数据库的维护(二)__触发器

    --维护数据库-- --触发器-- --概述: 触发器是一种特殊类型的存储过程,用来强制执行业务规则.在调用执上,触发器不能像存储过程那样可以由用户通过T-SQL语句直接调用,而是需要有数据库所发生的 ...

  6. 选项卡切换:自动定时&主动触发事件

    最初学习的是手动触发事件,添加的是onmouseover,其中index是关键,tab标签与现实内容的div索引一一对应,遍历tab标签,当鼠标移动到某标签时,触发对应的内容div显示.for(var ...

  7. UVa 488 - Triangle Wave

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...

  8. C#网络编程二:Socket编程

    一:什么是SOCKET socket的英文原义是"孔"或"插座".作为进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端 ...

  9. linux下服务端实现公网数据转发

    之前在腾讯上使用了一个免费的公网服务器,只有7天,linux系统. 其实有这样的想法,是因为有个研二的师弟问我怎么样才能让连个局域网的电脑通信. 我跟他说了两种方法,一种是找个公网服务器来转发数据,另 ...

  10. [2015hdu多校联赛补题]hdu5384 Danganronpa

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:函数f(A, B)定义:A.B为字符串,f(A, B)为A中有多少个不同的B(ex:f(& ...