Skip to content

Instantly share code, notes, and snippets.

@aimore
Last active August 15, 2022 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aimore/8dc3e0d36651a11936b6d4a70b66c3de to your computer and use it in GitHub Desktop.
Save aimore/8dc3e0d36651a11936b6d4a70b66c3de to your computer and use it in GitHub Desktop.
html to PDF
using System;
using System.Drawing;
using System.IO;
using CatCatalog.iOS.Services;
using CatCatalog.Services;
using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(PdfConverter))]
namespace CatCatalog.iOS.Services
{
public class PdfConverter : IPdfConverter
{
public string SafeHTMLToPDF(string html, string filename)
{
UIWebView webView = new UIWebView(new CGRect(0, 0, 6.5 * 72, 9 * 72));
html = @"<!doctype html>
<html>
<head>
<meta charset=""utf-8"">
<title>A simple, clean, and responsive HTML invoice template</title>
<style>
.invoice-box {
max-width: 800px;
margin: auto;
padding: 30px;
border: 1px solid #eee;
box-shadow: 0 0 10px rgba(0, 0, 0, .15);
font-size: 16px;
line-height: 24px;
font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
color: #555;
}
.invoice-box table {
width: 100%;
line-height: inherit;
text-align: left;
}
.invoice-box table td {
padding: 5px;
vertical-align: top;
}
.invoice-box table tr td:nth-child(2) {
text-align: right;
}
.invoice-box table tr.top table td {
padding-bottom: 20px;
}
.invoice-box table tr.top table td.title {
font-size: 45px;
line-height: 45px;
color: #333;
}
.invoice-box table tr.information table td {
padding-bottom: 40px;
}
.invoice-box table tr.heading td {
background: #eee;
border-bottom: 1px solid #ddd;
font-weight: bold;
}
.invoice-box table tr.details td {
padding-bottom: 20px;
}
.invoice-box table tr.item td{
border-bottom: 1px solid #eee;
}
.invoice-box table tr.item.last td {
border-bottom: none;
}
.invoice-box table tr.total td:nth-child(2) {
border-top: 2px solid #eee;
font-weight: bold;
}
@media only screen and (max-width: 600px) {
.invoice-box table tr.top table td {
width: 100%;
display: block;
text-align: center;
}
.invoice-box table tr.information table td {
width: 100%;
display: block;
text-align: center;
}
}
/** RTL **/
.rtl {
direction: rtl;
font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
}
.rtl table {
text-align: right;
}
.rtl table tr td:nth-child(2) {
text-align: left;
}
</style>
</head>
<body>
<div class=""invoice-box"">
<table cellpadding=""0"" cellspacing=""0"">
<tr class=""top"">
<td colspan=""2"">
<table>
<tr>
<td class=""title"">
<img src=""https://d2oc0ihd6a5bt.cloudfront.net/wp-content/uploads/sites/1044/2018/08/Westrac-Logo.jpg"" style=""width:100%; max-width:300px;"">
</td>
<td>
Invoice #: 123<br>
Created: December 6, 2018 12:41pm<br>
Due: December 6, 2018
</td>
</tr>
</table>
</td>
</tr>
<tr class=""information"">
<td colspan=""2"">
<table>
<tr>
<td>
Aimoresc, Inc.<br>
12345 Porter Street<br>
Ryde, NSW 2112
</td>
<td>
XAM Consulting Pty.<br>
Drew Alexander<br>
drew@example.com
</td>
</tr>
</table>
</td>
</tr>
<tr class=""heading"">
<td>
Payment Method
</td>
<td>
Check #
</td>
</tr>
<tr class=""details"">
<td>
Check
</td>
<td>
1000
</td>
</tr>
<tr class=""heading"">
<td>
Item
</td>
<td>
Price
</td>
</tr>
<tr class=""item"">
<td>
Sideshift machine
</td>
<td>
$70000.00
</td>
</tr>
<tr class=""item"">
<td>
Augers (Worktool)
</td>
<td>
$200.00
</td>
</tr>
<tr class=""item last"">
<td>
Commission (8%)
</td>
<td>
$5616.00
</td>
</tr>
<tr class=""total"">
<td></td>
<td>
Total: $75816.00
</td>
</tr>
</table>
</div>
</body>
</html>";
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var file = Path.Combine(documents, "Invoice.pdf");
webView.Delegate = new WebViewCallBack(file);
webView.ScalesPageToFit = true;
webView.UserInteractionEnabled = false;
webView.BackgroundColor = UIColor.White;
webView.LoadHtmlString(html, null);
OpenFile(file);
return file;
}
private void OpenFile(string filePath)
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
//string filePath = Path.Combine(path, "sample.pdf");
var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(filePath));
viewer.PresentOpenInMenu(new RectangleF(0, -260, 320, 320), vc.View, true);
}
class WebViewCallBack : UIWebViewDelegate
{
string filename = null;
public WebViewCallBack(string path)
{
this.filename = path;
}
public override void LoadingFinished(UIWebView webView)
{
double height, width;
int header, sidespace;
width = 595.2;
height = 841.8;
header = 10;
sidespace = 10;
UIEdgeInsets pageMargins = new UIEdgeInsets(header, sidespace, header, sidespace);
webView.ViewPrintFormatter.ContentInsets = pageMargins;
UIPrintPageRenderer renderer = new UIPrintPageRenderer();
renderer.AddPrintFormatter(webView.ViewPrintFormatter, 0);
CGSize pageSize = new CGSize(width, height);
CGRect printableRect = new CGRect(sidespace,
header,
pageSize.Width - (sidespace * 2),
pageSize.Height - (header * 2));
CGRect paperRect = new CGRect(0, 0, width, height);
renderer.SetValueForKey(NSValue.FromObject(paperRect), (NSString)"paperRect");
renderer.SetValueForKey(NSValue.FromObject(printableRect), (NSString)"printableRect");
NSData file = PrintToPDFWithRenderer(renderer, paperRect);
File.WriteAllBytes(filename, file.ToArray());
}
private NSData PrintToPDFWithRenderer(UIPrintPageRenderer renderer, CGRect paperRect)
{
NSMutableData pdfData = new NSMutableData();
UIGraphics.BeginPDFContext(pdfData, paperRect, null);
renderer.PrepareForDrawingPages(new NSRange(0, renderer.NumberOfPages));
CGRect bounds = UIGraphics.PDFContextBounds;
for (int i = 0; i < renderer.NumberOfPages; i++)
{
UIGraphics.BeginPDFPage();
renderer.DrawPage(i, paperRect);
}
UIGraphics.EndPDFContent();
return pdfData;
}
}
}
}
public void OpenFile(string filePath)
{
var bytes = File.ReadAllBytes(filePath);
//Copy the private file's data to the EXTERNAL PUBLIC location
string externalStorageState = global::Android.OS.Environment.ExternalStorageState;
string application = "";
string extension = System.IO.Path.GetExtension (filePath);
switch (extension.ToLower()) {
case ".doc":
case ".docx":
application = "application/msword";
break;
case ".pdf":
application = "application/pdf";
break;
case ".xls":
case ".xlsx":
application = "application/vnd.ms-excel";
break;
case ".jpg":
case ".jpeg":
case ".png":
application = "image/jpeg";
break;
default:
application = "*/*";
break;
}
var externalPath = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/report" + extension;
File.WriteAllBytes(externalPath, bytes);
Java.IO.File file = new Java.IO.File(externalPath);
file.SetReadable(true);
//Android.Net.Uri uri = Android.Net.Uri.Parse("file://" + filePath);
Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(uri, application);
intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
try
{
Xamarin.Forms.Forms.Context.StartActivity(intent);
}
catch (Exception)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "No Application Available to View PDF", ToastLength.Short).Show();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment