gpt4 book ai didi

c# - 通过 Xamarin.Forms 在 Android 上打印本地文件

转载 作者:行者123 更新时间:2023-11-30 00:35:14 26 4
gpt4 key购买 nike

我需要通过表单使用打印对话框。我在 iOS 上找到了解决方案,但 android 实现给我带来了问题。

据我所知,调用 Android 打印管理器并向其解析文件是不可能的。它只能是一个 Android.Views.View,是这样吗?这样做是我理想的解决方案。

我试图将我的内容(一个显示本地 pdf 的 WebView )转换为这个 android View ,但这似乎也没有真正起作用,但我在这里超出了我的深度。

在下面的代码中,我尝试将 forms.webview 转换为 android.view,然后将其解析到打印管理器。这会生成打印对话框,但页面是黑白的。

var size = new Rectangle(webview.X, webview.Y, webview.Width, webview.Height);
var vRenderer = Xamarin.Forms.Platform.Android.Platform.CreateRenderer(webview);
var viewGroup = vRenderer.ViewGroup;
vRenderer.Tracker.UpdateLayout();
var layoutParams = new Android.Views.ViewGroup.LayoutParams((int)size.Width, (int)size.Height);
viewGroup.LayoutParameters = layoutParams;
webview.Layout(size);
viewGroup.Layout(0, 0, (int)webview.WidthRequest, (int)webview.HeightRequest);

var printMgr = (Android.Print.PrintManager)Forms.Context.GetSystemService(Android.Content.Context.PrintService);
var docAdt = new Droid.GenericPrintAdapter(Forms.Context, viewGroup);

printMgr.Print("test", docAdt, null);

接下来是“GenericPrintAdapter”

public class GenericPrintAdapter : PrintDocumentAdapter
{
View view;
Context context;
PrintedPdfDocument document;
float scale;

public GenericPrintAdapter(Context context, View view)
{
this.view = view;
this.context = context;
}

public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras)
{
document = new PrintedPdfDocument(context, newAttributes);

CalculateScale(newAttributes);

var printInfo = new PrintDocumentInfo
.Builder("MyPrint.pdf")
.SetContentType(PrintContentType.Document)
.SetPageCount(1)
.Build();

callback.OnLayoutFinished(printInfo, true);
}

void CalculateScale(PrintAttributes newAttributes)
{
int dpi = Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi);

int leftMargin = (int)(dpi * (float)newAttributes.MinMargins.LeftMils / 1000);
int rightMargin = (int)(dpi * (float)newAttributes.MinMargins.RightMils / 1000);
int topMargin = (int)(dpi * (float)newAttributes.MinMargins.TopMils / 1000);
int bottomMargin = (int)(dpi * (float)newAttributes.MinMargins.BottomMils / 1000);

int w = (int)(dpi * (float)newAttributes.GetMediaSize().WidthMils / 1000) - leftMargin - rightMargin;
int h = (int)(dpi * (float)newAttributes.GetMediaSize().HeightMils / 1000) - topMargin - bottomMargin;

scale = Math.Min((float)document.PageContentRect.Width() / w, (float)document.PageContentRect.Height() / h);
}

public override void OnWrite(PageRange[] pages, ParcelFileDescriptor destination,
CancellationSignal cancellationSignal, WriteResultCallback callback)
{
PrintedPdfDocument.Page page = document.StartPage(0);

page.Canvas.Scale(scale, scale);

view.Draw(page.Canvas);

document.FinishPage(page);

WritePrintedPdfDoc(destination);

document.Close();

document.Dispose();

callback.OnWriteFinished(pages);
}

void WritePrintedPdfDoc(ParcelFileDescriptor destination)
{
var javaStream = new Java.IO.FileOutputStream(destination.FileDescriptor);
var osi = new OutputStreamInvoker(javaStream);
using (var mem = new MemoryStream())
{
document.WriteTo(mem);
var bytes = mem.ToArray();
osi.Write(bytes, 0, bytes.Length);
}
}
}

最佳答案

我现在有了一个“有效”的解决方案。

这会获取当前的 Android.Webkir.WebView 并从中创建 printAdapter。

感谢@SushiHangover 为我指明了正确的方向。

它有点乱,但可以满足我的需要。

如果其他人需要这个,我已经包含了 Android 和 iOS 代码。

#if __ANDROID__
var vRenderer = Xamarin.Forms.Platform.Android.Platform.GetRenderer(webview);
var viewGroup = vRenderer.ViewGroup;

for (int i = 0; i < viewGroup.ChildCount; i++)
{
if (viewGroup.GetChildAt(i).GetType().Name == "WebView")
{
var AndroidWebView = viewGroup.GetChildAt(i) as Android.Webkit.WebView;
var tmp = AndroidWebView.CreatePrintDocumentAdapter("print");
var printMgr = (Android.Print.PrintManager)Forms.Context.GetSystemService(Android.Content.Context.PrintService);
printMgr.Print("print", tmp, null);
break;
}
}
#elif __IOS__
var printInfo = UIKit.UIPrintInfo.PrintInfo;
printInfo.Duplex = UIKit.UIPrintInfoDuplex.LongEdge;
printInfo.OutputType = UIKit.UIPrintInfoOutputType.General;
printInfo.JobName = "AppPrint";
var printer = UIKit.UIPrintInteractionController.SharedPrintController;
printer.PrintInfo = printInfo;
printer.PrintingItem = Foundation.NSData.FromFile(pdfPath);
printer.ShowsPageRange = true;
printer.Present(true, (handler, completed, err) =>
{
if (!completed && err != null)
{
System.Diagnostics.Debug.WriteLine("Printer Error");
}
});
#endif

关于c# - 通过 Xamarin.Forms 在 Android 上打印本地文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43520769/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com