C# Xamarin Android打印PDF文件
我正在尝试打印使用C# Xamarin Android打印PDF文件,c#,android,pdf,xamarin,printing,C#,Android,Pdf,Xamarin,Printing,我正在尝试打印使用PrintManager创建的PDF文件。我已经在活动中使用ITextSharp编写了生成PDF文件的代码。下面是我的生成PDF方法: private byte[] generatePdf() { using (var baos = new MemoryStream()) { using (var ps = new StreamWriter(baos)) {
PrintManager
创建的PDF文件。我已经在活动中使用ITextSharp
编写了生成PDF文件的代码。下面是我的生成PDF方法:
private byte[] generatePdf()
{
using (var baos = new MemoryStream())
{
using (var ps = new StreamWriter(baos))
{
Document doc = new Document(PageSize.A4, 72, 72, 72, 72);
PdfWriter writer = PdfWriter.GetInstance(doc, ps.BaseStream);
if (!doc.IsOpen())
doc.Open();
doc.AddTitle("Sales Order " + GlobalVars.selectedSales.DocumentNo);
var TitleFont = new Font(Font.FontFamily.TIMES_ROMAN, 24, Font.BOLD);
var SubTitleFont = new Font(Font.FontFamily.TIMES_ROMAN, 20);
var HeadingFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
var BoldNormalFont = new Font(Font.FontFamily.TIMES_ROMAN, 14, Font.BOLD);
var NormalFont = new Font(Font.FontFamily.TIMES_ROMAN, 14);
doc.Add(new Paragraph("SALES ORDER", TitleFont));
... //other data
doc.Close();
writer.Close();
}
var bytes = baos.ToArray();
return bytes;
}
}
简而言之,上面的代码将返回包含生成的PDF文件的字节数组,因为我不想将PDF保存在Android设备的任何位置
生成此PDF后,我无法使用PrintManager
,它只使用PrintDocumentAdapter
参数生成文件,而不使用生成的PDF。我正在尝试生成继承自PrintDocumentAdapter
的CustomPrintAdapter
,但不知道如何重用我在活动中创建的PDF,因为它使用PrintedPdfDocument
数据类型
你们能给我指一下正确的方向吗?或者有没有其他更容易实现打印自定义PDF文件的方法
更新1
基于本文,Xamarin Android不支持System.Drawing.dll。我认为ITextSharp库使用System.Drawing库,因为当我尝试构建它时,它引发了一个异常:
Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Perhaps it doesn't exist in the Mono for Android profile?
当我删除它时,构建成功,没有出现异常。请注意,我已尝试关闭解决方案,从Packages文件夹中删除所有内容,重新打开解决方案,然后构建;在这种情况下,它不起作用
因此,我将尝试使用Android开发者网站上的
Android.Graphics.Canvas
生成PDF。更新2
我没有像以前那样用Android.Graphics.Canvas成功生成PDF。原因是我不知道如何计算页面和更改页面,因为内容是动态的。该站点中还有一个类似于getPrintItemCount()
的方法,我不知道这是什么,因为该站点没有包含其中的解释
因此,我现在可以想到的解决方法是打印WebView
,这是由我的web服务端点处理的。我正在为要打印的页面创建HTML布局,然后WebView
将打开我的web服务端点。幸运的是,使用这种方法可以很好地进行打印。当然,这种方法也有局限性,即web服务应该可以访问以进行打印
为此,首先,我需要创建一个自定义类,该类扩展WebViewClient
,以便在使用OnPageFinished
方法完成页面加载时获取事件。一、 然后使用活动中的print方法,我使用构造函数传递它。为了更清楚,我将附上我的代码
public class CustomWebViewClient : WebViewClient
{
private SalesDetailView myActivity;
public bool shouldOverrideUrlLoading(WebView view, string url)
{
return false;
}
public override void OnPageFinished(WebView view, string url)
{
Log.Debug("PRINT", "page finished loading " + url);
myActivity.doWebViewPrint(url);
base.OnPageFinished(view, url);
}
public CustomWebViewClient(SalesDetailView activity)
{
myActivity = activity;
}
}
这是我活动中的doWebPrint方法
public async void doWebViewPrint(string URL)
{
if (await vm.printCheck())
{
PrintDocumentAdapter adapter;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
adapter = webView.CreatePrintDocumentAdapter("test");
else
adapter = webView.CreatePrintDocumentAdapter();
var printMgr = (PrintManager)GetSystemService(PrintService);
printMgr.Print("printTest", adapter, null);
}
}
然后我创建WebView
,每当用户单击打印按钮时加载网站
Button btnPrintSO = FindViewById<Button>(Resource.Id.btnPrintSO);
btnPrintSO.Click += delegate
{
string URL = ServerDatabaseApi.printSOEndpoint + GlobalVars.selectedSales.DocumentNo;
webView = new WebView(this);
CustomWebViewClient client = new CustomWebViewClient(this);
webView.SetWebViewClient(client);
webView.Settings.JavaScriptEnabled = true;
webView.LoadUrl(URL);
webView.Settings.UseWideViewPort = true;
webView.Settings.LoadWithOverviewMode = true;
};
按钮btnPrintSO=findviewbyd(Resource.Id.btnPrintSO);
btnPrintSO.Click+=委托
{
字符串URL=ServerDatabaseApi.PrintsEndPoint+GlobalVars.selectedSales.DocumentNo;
webView=新的webView(此);
CustomWebViewClient=新的CustomWebViewClient(此);
SetWebViewClient(客户端);
webView.Settings.JavaScriptEnabled=true;
LoadUrl(URL);
webView.Settings.UseWideViewPort=true;
webView.Settings.LoadWithOverviewMode=true;
};
希望这些更新能帮助将来的任何人。你可以在本地构建html,不是吗?@VassilisGr你是说在Android上?当然可以。我更喜欢在服务器上构建html,以便Android接收最终数据(html),这意味着Android可以直接使用数据。