Changing Printer Support File Path in Forge Design Automation API - autodesk-forge

In AutoCAD Design Automation API - How would one go about changing the Options --> Files (tab) --> Printer Support File Path --> Plot Style Table Search Path to point to another location during a work item execution? I have tried adjusting the RuntimeRequirements in the package contents xml file to point to my bundle contents, but that did not work.
<Components>
<RuntimeRequirements
OS="Win64"
Platform="AutoCAD"
SupportPath="./Contents/"/>
............
Any Suggestions? Ultimately im trying to upload a specific custom ctb file and plot with it
Thanks,
John

You need to program to copy the related files from bundle to Plotter folders in your custom plugin dll.
Suppose you placed all the related files like .pmp,.pc3 and .ctb in Contents folder, as shown in pic
Example:
Then you need to run command, prior to running any PLOT commands. This will copy files to relevant folders when your execute workItem against the bundle package you have uploaded to DA service.
[CommandMethod("PlotLayoutCommands", "COPYPLOTTERFILES", CommandFlags.Modal)]
public static void CopyPlotterFiles()
{
// Get the current document and database, and start a transaction
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
//A way to copy files from bundle package to respective Printer Support Path
object roamablePath = Autodesk.AutoCAD.ApplicationServices.Core.Application.GetSystemVariable("ROAMABLEROOTPREFIX");
acDoc.Editor.WriteMessage("\nRoamable-Path\t:{0}\n", roamablePath.ToString());
string pc3FileFound = HostApplicationServices.Current.FindFile("DAS-PDF.pc3", acCurDb, FindFileHint.Default);
string pmpFileFound = HostApplicationServices.Current.FindFile("DAS-PDF.pmp", acCurDb, FindFileHint.Default);
string plotStyleFileFound = HostApplicationServices.Current.FindFile("DAS-PDF.ctb", acCurDb, FindFileHint.Default);
string scriptFileFound = HostApplicationServices.Current.FindFile("RunPlot.scr", acCurDb, FindFileHint.Default);
acDoc.Editor.WriteMessage("\nPC3 Config\t:{0}\n", pc3FileFound);
acDoc.Editor.WriteMessage("\nPMP File\t:{0}\n", pmpFileFound);
acDoc.Editor.WriteMessage("\nCTB File\t:{0}\n", plotStyleFileFound);
acDoc.Editor.WriteMessage("\nScript File\t:{0}\n", scriptFileFound);
//Start Copying:
string pmpFolder = "PMP Files";
string pc3Folder = "Plotters";
string plotStylesFolder = "Plot Styles";
try
{
File.Copy(pc3FileFound,
Path.Combine(roamablePath.ToString(),
pc3Folder, Path.GetFileName(pc3FileFound)));
File.Copy(pmpFileFound,
Path.Combine(roamablePath.ToString(),
pc3Folder, pmpFolder, Path.GetFileName(pmpFileFound)));
File.Copy(plotStyleFileFound, Path.Combine(roamablePath.ToString(),
pc3Folder, plotStylesFolder, Path.GetFileName(plotStyleFileFound)));
File.Copy(scriptFileFound, Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(plotStyleFileFound)));
}
catch (System.Exception ex)
{
acDoc.Editor.WriteMessage("\n" + ex.Message);
}
}
or
You can create CustomPlot command something like this, which will set PC3 and CTB on the Layout.
public static void PlotLayout()
{
// Get the current document and database, and start a transaction
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
//A way to copy files from bundle package to respective Printer Support Path
object roamablePath = Autodesk.AutoCAD.ApplicationServices.Core.Application.GetSystemVariable("ROAMABLEROOTPREFIX");
acDoc.Editor.WriteMessage("\nRoamable-Path\t:{0}\n", roamablePath.ToString());
string pc3FileFound = HostApplicationServices.Current.FindFile("DAS-PDF.pc3", acCurDb, FindFileHint.Default);
string pmpFileFound = HostApplicationServices.Current.FindFile("DAS-PDF.pmp", acCurDb, FindFileHint.Default);
string plotStyleFileFound = HostApplicationServices.Current.FindFile("DAS-PDF.ctb", acCurDb, FindFileHint.Default);
acDoc.Editor.WriteMessage("\nPC3 Config\t:{0}\n", pc3FileFound);
acDoc.Editor.WriteMessage("\nPMP File\t:{0}\n", pmpFileFound);
acDoc.Editor.WriteMessage("\nCTB File\t:{0}\n", plotStyleFileFound);
//Start Copying:
string pmpFolder = "PMP Files";
string pc3Folder = "Plotters";
string plotStylesFolder = "Plot Styles";
try
{
File.Copy(pc3FileFound,
Path.Combine(roamablePath.ToString(),
pc3Folder, Path.GetFileName(pc3FileFound)),true);
File.Copy(pmpFileFound,
Path.Combine(roamablePath.ToString(),
pc3Folder, pmpFolder, Path.GetFileName(pmpFileFound)), true);
File.Copy(plotStyleFileFound, Path.Combine(roamablePath.ToString(),
pc3Folder, plotStylesFolder, Path.GetFileName(plotStyleFileFound)), true);
}
catch (System.Exception ex)
{
acDoc.Editor.WriteMessage("\n" + ex.Message);
}
// these prompts are only seen when running in interactive mode in autocad
// when they are run from the activity, they are passed in as part of the script (like parameters)
PromptResult result = acDoc.Editor.GetString("Enter PC3 File:");
if (result.Status != PromptStatus.OK) return;
string pc3FileName = result.StringResult;
result = acDoc.Editor.GetString("Enter CTB File:");
if (result.Status != PromptStatus.OK) return;
string ctbFileName = result.StringResult;
result = acDoc.Editor.GetString("Enter PDF Name :");
if (result.Status != PromptStatus.OK) return;
string pdfFileName = result.StringResult;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Reference the Layout Manager
LayoutManager acLayoutMgr = LayoutManager.Current;
// Get the current layout and output its name in the Command Line window
Layout acLayout = acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout),
OpenMode.ForRead) as Layout;
using (OpenCloseTransaction oct = new OpenCloseTransaction())
{
using (PlotSettingsValidator plotSetVal = PlotSettingsValidator.Current)
{
acDoc.Editor.WriteMessage($"\nStyle sheet of current layout:{acLayout.CurrentStyleSheet}");
if (!acLayout.IsWriteEnabled)
{
acLayout.UpgradeOpen();
}
plotSetVal.RefreshLists(acLayout);
if (plotSetVal.GetPlotStyleSheetList().Contains(ctbFileName))
{
if (acCurDb.PlotStyleMode)
{
acDoc.Editor.WriteMessage($"\nThe plot style sheet is being set to {ctbFileName}");
plotSetVal.SetCurrentStyleSheet(acLayout, ctbFileName);
}
else
{
acDoc.Editor.WriteMessage("\nUnable to set plot style in drawing using stb\n\n");
}
}
}
oct.Commit();
}
PlotConfig acPlCfg = PlotConfigManager.SetCurrentConfig(pc3FileName);
string mediaName = acPlCfg.Comment;
// Get the PlotInfo from the layout
using (PlotInfo acPlInfo = new PlotInfo())
{
acPlInfo.Layout = acLayout.ObjectId;
// Get a copy of the PlotSettings from the layout
using (PlotSettings acPlSet = new PlotSettings(acLayout.ModelType))
{
acPlSet.CopyFrom(acLayout);
// Update the PlotSettings object
PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
// Set the plot type
acPlSetVdr.SetPlotType(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents);
// Set the plot scale
acPlSetVdr.SetUseStandardScale(acPlSet, true);
acPlSetVdr.SetStdScaleType(acPlSet, StdScaleType.ScaleToFit);
// Center the plot
acPlSetVdr.SetPlotCentered(acPlSet, true);
// Set the plot device to use
acPlSetVdr.SetPlotConfigurationName(acPlSet, Path.GetFileName(pc3FileName), acPlSet.CanonicalMediaName);
// Set the plot info as an override since it will
// not be saved back to the layout
acPlInfo.OverrideSettings = acPlSet;
// Validate the plot info
using (PlotInfoValidator acPlInfoVdr = new PlotInfoValidator())
{
acPlInfoVdr.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
acPlInfoVdr.Validate(acPlInfo);
// Check to see if a plot is already in progress
if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
{
using (PlotEngine acPlEng = PlotFactory.CreatePublishEngine())
{
// Track the plot progress with a Progress dialog
using (PlotProgressDialog acPlProgDlg = new PlotProgressDialog(false, 1, true))
{
using ((acPlProgDlg))
{
// Define the status messages to display
// when plotting starts
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.DialogTitle, "Plot Progress");
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "Cancel Job");
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "Cancel Sheet");
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress");
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress");
// Set the plot progress range
acPlProgDlg.LowerPlotProgressRange = 0;
acPlProgDlg.UpperPlotProgressRange = 100;
acPlProgDlg.PlotProgressPos = 0;
// Display the Progress dialog
acPlProgDlg.OnBeginPlot();
acPlProgDlg.IsVisible = true;
// Start to plot the layout
acPlEng.BeginPlot(acPlProgDlg, null);
// Define the plot output
acPlEng.BeginDocument(acPlInfo, acDoc.Name, null, 1, true, pdfFileName);
// Display information about the current plot
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.Status, "Plotting: " + acDoc.Name + " - " + acLayout.LayoutName);
// Set the sheet progress range
acPlProgDlg.OnBeginSheet();
acPlProgDlg.LowerSheetProgressRange = 0;
acPlProgDlg.UpperSheetProgressRange = 100;
acPlProgDlg.SheetProgressPos = 0;
// Plot the first sheet/layout
using (PlotPageInfo acPlPageInfo = new PlotPageInfo())
{
acPlEng.BeginPage(acPlPageInfo, acPlInfo, true, null);
}
acPlEng.BeginGenerateGraphics(null);
acPlEng.EndGenerateGraphics(null);
// Finish plotting the sheet/layout
acPlEng.EndPage(null);
acPlProgDlg.SheetProgressPos = 100;
acPlProgDlg.OnEndSheet();
// Finish plotting the document
acPlEng.EndDocument(null);
// Finish the plot
acPlProgDlg.PlotProgressPos = 100;
acPlProgDlg.OnEndPlot();
acPlEng.EndPlot(null);
}
}
}
}
}
}
}
}
}
Your Activity using C# .NET core.
private async Task<string> SetupActivityAsync(string myApp)
{
Console.WriteLine("Setting up activity...");
var myActivity = $"{Owner}.{ActivityName}+{Label}";
var actResponse = await this.api.ActivitiesApi.GetActivityAsync(myActivity, throwOnError: false);
var activity = new Activity()
{
Appbundles = new List<string>()
{
myApp
},
CommandLine = new List<string>()
{
$"$(engine.path)\\accoreconsole.exe /i $(args[inputFile].path) /al $(appbundles[{PackageName}].path) /s $(settings[script].path)"
},
Engine = TargetEngine,
Settings = new Dictionary<string, ISetting>()
{
{ "script", new StringSetting() { Value = "CustomPlot\nDAS-PDF.pc3\nDAS-PDF.ctb\nresult.pdf\n" } }
},
Parameters = new Dictionary<string, Parameter>()
{
{ "inputFile", new Parameter() { Verb= Verb.Get, LocalName = "$(HostDwg)", Required = true } },
{ "outputFile", new Parameter() { Verb= Verb.Put, LocalName = "result.pdf", Required= true} }
},
Id = ActivityName
};
if (actResponse.HttpResponse.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine($"Creating activity {myActivity}...");
await api.CreateActivityAsync(activity, Label);
return myActivity;
}
await actResponse.HttpResponse.EnsureSuccessStatusCodeAsync();
Console.WriteLine("\tFound existing activity...");
if (!Equals(activity, actResponse.Content))
{
Console.WriteLine($"\tUpdating activity {myActivity}...");
await api.UpdateActivityAsync(activity, Label);
}
return myActivity;
}
And, Workitem:
var workItemStatus = await api.CreateWorkItemAsync(new Autodesk.Forge.DesignAutomation.Model.WorkItem()
{
ActivityId = myActivity,
Arguments = new Dictionary<string, IArgument>() {
{
"inputFile",
new XrefTreeArgument() {
Url = DownloadUrl,
Verb = Verb.Get
}
}, {
"outputFile",
new XrefTreeArgument() {
Verb = Verb.Put, Url = UploadUrl
}
}
}
});

Related

Downloading Attachment from Exchange Server using SSIS package deployed on another Server

I have built an SSIS package which reads CSV from certain folder. But now I need to download same csv from exchange server.Also Outlook is not installed on my machine. Will I be able to download CSV from exchange server and how ? Thanks!
I have used some of the code from the link http://sqlandbilearning.blogspot.com.au/2014/07/download-email-attachment-using-ssis.html but i have added some new code for removing TCP binding error using ServicePointManager as well as added search filter for retrieving specific emails and this code also takes care of multiple attachment from different emails to be saved on file system.
public void Main()
{
string filePath = "";
string fileName = "";
List<SearchFilter> searchFilterCollection = new List<SearchFilter>();
DateTime now = DateTime.Now;
DateTime beginRecievedTime = new DateTime(now.Year, now.Month, now.Day, 7, 55, 0);
DateTime finishRecievedTime = new DateTime(now.Year, now.Month, now.Day, 8, 15, 0);
EmailMessage latestEmail = null;
try
{
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.UseDefaultCredentials = true;
//service.Credentials = new WebCredentials("username", "password");
service.Url = new Uri("");
// 10 mails per page in DESC order
ItemView view = new ItemView(10);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "Scheduled search"));
SearchFilter greaterthanfilter = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, beginRecievedTime);
searchFilterCollection.Add(greaterthanfilter);
SearchFilter lessthanfilter = new SearchFilter.IsLessThan(ItemSchema.DateTimeReceived, finishRecievedTime);
searchFilterCollection.Add(lessthanfilter);
SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilterCollection);
//Find mails
FindItemsResults<Item> fir = service.FindItems(WellKnownFolderName.Inbox, filter, view);
Dictionary<EmailMessage, string> emailsMap = new Dictionary<EmailMessage, string>();
foreach (Item item in fir.Items)
{
item.Load(); //Load the entire message with attachment
EmailMessage email = item as EmailMessage;
if (email != null)
{
if (email.HasAttachments == true && email.Attachments.Count == 1)
{
if (email.Subject.StartsWith("Scheduled search") == true)
{
filePath = Path.Combine(Dts.Variables["User::SourceFolderPath"].Value.ToString()
, email.DateTimeReceived.Date.ToString("MM.dd.yyyy") + "_" +
email.Attachments[0].Name);
// fileName = email.DateTimeReceived.Date.ToString("MM.dd.yyyy") + "_" +
// email.Attachments[0].Name.ToString();
emailsMap.Add(email, filePath);
}
}
}
}
if (emailsMap.Count > 0) {
foreach (var item in emailsMap) {
//Save attachment
EmailMessage email = item.Key;
filePath = item.Value;
FileAttachment fileAttachment = email.Attachments[0] as FileAttachment;
fileAttachment.Load(filePath);
string extractPath = Dts.Variables["User::SourceFolderPath"].Value.ToString() + "\\" + email.Attachments[0].Name;
System.IO.Compression.ZipFile.ExtractToDirectory(filePath, extractPath);
fileName = Dts.Variables["User::SourceFolderPath"].Value.ToString() + "\\" + email.DateTimeReceived.Date.ToString("MM.dd.yyyy") + "_" +
email.Attachments[0].Name.ToString();
if (File.Exists(fileName))
{
File.Delete(fileName);
}
}
}
// Dts.Variables["User::SourceFileName"].Value = fileName;
Dts.TaskResult = (int)ScriptResults.Success;
}
catch(System.Runtime.InteropServices.COMException ex)
{
if (Dts.Variables.Locked == true)
{
Dts.Variables.Unlock();
}
//An error occurred.
Dts.Events.FireError(0, "Error occured", ex.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}

Simple autocomplete with Ace Editor in AS3?

I'm working in XML and I'd like to provide autocomplete suggestions for the attributes for specific node types using AS3.
For example, if the user is has a cursor in the following node:
<s:Button label="Hello World"/>
I'd like autocomplete to show "width, height, x, y".
I'm trying to get the node name and namespace and then give the editor a list of attributes that should appear in autocomplete.
I found similar questions but those are using a service call and a few that are out dated. I may delete this question if it is a duplicate.
Ace Editor for AS3 here.
In my case, for AS3, it is a combination of items:
ace.setCompleters(null); // I'm removing existing autocomplete
ace.addCompleter(codeCompleter); // adding my own
public var autoCompleteErrorMessage:String = "Nothing available";
public function codeCompleter(editor:Object, session:Object, position:Object, prefix:String, callback:Function):void {
var row:int = position.row;
var column:int = position.column;
/*
if (prefix.length === 0) {
callback(null, []);
return;
}
*/
//var myList:Array = {value: "message", caption: "Caption to user", meta: "Type shown", score: "I don't know"};
var testing:Boolean = false;
if (testing) {
callback(autoCompleteErrorMessage, [{value:"addedToStage"},{value:"added"},{value:"adding"}]);
}
else {
callback(autoCompleteErrorMessage, attributes);
}
}
protected function cursorChangeHandler(event:Event):void {
var qname:QName = getQNameFromCursorPosition(ace.row, ace.column);
if (qname==null) {
if (attributes.length) {
attributes = [];
}
return;
}
if (qname) {
attributes = getSuggestionListFromObject(classObject);
autoCompleteErrorMessage = null;
lastSelectedQName = qname;
}
}
public static var XML_TAG_NAME:String = "meta.tag.tag-name.xml";
public static var XML_TAG_OPEN:String = "meta.tag.punctuation.tag-open.xml";
public static var XML_TAG_CLOSE:String = "meta.tag.punctuation.tag-close.xml";
public static var XML_ATTRIBUTE_NAME:String = "entity.other.attribute-name.xml";
public function getQNameFromCursorPosition(row:int, column:int):QName {
var token:Object;
var line:String;
var type:String;
var value:String;
var found:Boolean;
var qname:QName;
for (; row > -1; row--) {
line = ace.getLine(row);
column = line.length;
for (; column>-1; column--) {
token = ace.getTokenAt(row, column);
type = token ? token.type : "";
if (type==XML_TAG_NAME) {
value = token.value;
found = true;
}
}
if (found) break;
}
if (found) {
qname = new QName("", value);
}
return qname;
}
The getQNameFromCursorPosition() method is fragile and I'm looking into a new method using the jumpToMatching() method.

Xamarin free HTML or DOC to PDF Conversion

I'm currently searching for a library or a way to convert HTML OR DOCX files into PDF on the phone/tab, primarily I'am searching for a way on Android or iOS idk if its a PCL or platform specific approach. I could do this for every Platform independently, because our app requires iOS 8 or android kitkat, both supporting native PDF conversion but i want to do it seamless for the user, so the question is, if anyone has done this before, without loading it into a visible Webview at first or has knowledge of an open not GPL licensed API(can't publish the code), to do this with Xamarin.
I am aware of the possibility to do this online, but I don't want to to be dependent to a online service for this.
Help and ideas are appreciated.
Android Solution:
Call the SafeHTMLToPDF(string html, string filename) via a dependency service like
DependencyService.Get<YOURINTERFACE>().SafeHTMLToPDF(htmlString, "Invoice");
public string SafeHTMLToPDF(string html, string filename)
{
var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/pay&go/");
var file = new Java.IO.File(dir + "/" + filename + ".pdf");
if (!dir.Exists())
dir.Mkdirs();
int x = 0;
while (file.Exists())
{
x++;
file= new Java.IO.File(dir + "/" + filename + "( " + x + " )" + ".pdf");
}
if (webpage == null)
webpage = new Android.Webkit.WebView(GetApplicationContext());
int width = 2102;
int height = 2973;
webpage.Layout(0, 0, width, height);
webpage.LoadDataWithBaseURL("",html, "text/html", "UTF-8" , null);
webpage.SetWebViewClient(new WebViewCallBack(file.ToString()));
return file.ToString();
}
class WebViewCallBack : WebViewClient
{
string fileNameWithPath = null;
public WebViewCallBack(string path)
{
this.fileNameWithPath = path;
}
public override void OnPageFinished(Android.Webkit.WebView myWebview, string url)
{
PdfDocument document = new PdfDocument();
PdfDocument.Page page = document.StartPage(new PdfDocument.PageInfo.Builder(2120 ,3000, 1).Create());
myWebview.Draw(page.Canvas);
document.FinishPage(page);
Stream filestream = new MemoryStream();
FileOutputStream fos = new Java.IO.FileOutputStream(fileNameWithPath, false); ;
try
{
document.WriteTo(filestream);
fos.Write(((MemoryStream)filestream).ToArray(), 0, (int)filestream.Length);
fos.Close();
}
catch
{
}
}
}
And the Way to do it under iOS
public string SafeHTMLToPDF(string html, string filename)
{
UIWebView webView = new UIWebView(new CGRect(0, 0, 6.5 * 72, 9 * 72));
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var file = Path.Combine(documents, "Invoice" + "_" + DateTime.Now.ToShortDateString() + "_" + DateTime.Now.ToShortTimeString() + ".pdf");
webView.Delegate = new WebViewCallBack(file);
webView.ScalesPageToFit = true;
webView.UserInteractionEnabled = false;
webView.BackgroundColor = UIColor.White;
webView.LoadHtmlString(html, null);
return file;
}
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;
}
}
Frustrated with the existing solutions, I've built some extension methods (OpenSource, MIT Licensed) that convert HTML or the content of a Xamarin.Forms.WebView to a PDF file. Sample usage for WebView to PDF:
async void ShareButton_Clicked(object sender, EventArgs e)
{
if (Forms9Patch.ToPdfService.IsAvailable)
{
if (await webView.ToPdfAsync("output.pdf") is ToFileResult pdfResult)
{
if (pdfResult.IsError)
using (Toast.Create("PDF Failure", pdfResult.Result)) { }
else
{
var collection = new Forms9Patch.MimeItemCollection();
collection.AddBytesFromFile("application/pdf", pdfResult.Result);
Forms9Patch.Sharing.Share(collection, shareButton);
}
}
}
else
using (Toast.Create(null, "PDF Export is not available on this device")) { }
}
}
For a more complete explanation of how to use it, here's a short article: https://medium.com/#ben_12456/share-xamarin-forms-webview-as-a-pdf-a877542e824a?
You can able to convert the HTML to PDF file without any third party library. I am sharing my git repo for future reference.
https://github.com/dinesh4official/XFPDF
Yes, you can convert a Word document to PDF in Xamarin with a few lines of code easily. You need to refer Syncfusion.Xamarin.DocIORenderer from nuget.org
Assembly assembly = typeof(App).GetTypeInfo().Assembly;
// Retrieves the document stream from embedded Word document
Stream inputStream = assembly.GetManifestResourceStream("WordToPDF.Assets.GettingStarted.docx");
string fileName = "GettingStarted.pdf";
// Creates new instance of WordDocument
WordDocument wordDocument = new WordDocument(inputStream,Syncfusion.DocIO.FormatType.Automatic);
inputStream.Dispose();
// Creates new instance of DocIORenderer for Word to PDF conversion
DocIORenderer render = new DocIORenderer();
// Converts Word document into PDF document
PdfDocument pdfDocument = render.ConvertToPDF(wordDocument);
// Releases all resources used by the DocIORenderer and WordDocument instance
render.Dispose();
document.Close();
// Saves the converted PDF file
MemoryStream outputStream = new MemoryStream();
pdfDocument.Save(outputStream);
// Releases all resources used by the PdfDocument instance
pdfDocument.Close();
To know more about this, kindly refer here.

How to get byteArray or base64 string from RenderTexture Cocos2d-JS

I am making a game on cocos2d-JS for facebook in which there is a requirement of sharing a screenshot of the game.
I am able to take the screenshot but now I am unable to upload it in the Parse.com server because it requires base64 format or byte array. I am unable to find any solution of converting Sprite in to this format.. Here's my code so result when I do addchild its coming proper .. I have also added my commented code so that it will help to understand that I have tried lot of things but couldnt achieve the same.
shareToSocialNetworking: function () {
cc.director.setNextDeltaTimeZero(true);
var newsize = cc.director.getVisibleSize();
var renderText = new cc.RenderTexture(newsize.width,newsize.height);
renderText.begin();
cc.director.getRunningScene().visit();
renderText.end();
var result = cc.Sprite.create(renderText.getSprite().getTexture());
result.flippedY = true;
this._mainViewNode.addChild(result,6000);
//renderText.saveToFile("screenshot.jpg",cc.IMAGE_FORMAT_PNG);
//var based = renderText.getSprite().getTexture().getStringForFormat().toString();
//var data = based.getData();
var file = new Parse.File("screen.jpg", { base64: this.getBase64(result) });
//var file = new Parse.File("screen.jpg", data, "image/png");
var self = this;
file.save().then(function() {
// The file has been saved to Parse.
alert(file.url);
this.onSharePictureInfoLink(file.url());
}, function(error) {
// The file either could not be read, or could not be saved to Parse.
});
//
//var ccImage = renderText.newCCImage();
//
//var str = ccImage.getData();
},
is there any workaround that can be done
there is a private variable called _cacheCanvas, which is the instance of the offscreen canvas
you can simply do renderText._cacheCanvas.toDataURL()
Here's how you can take the screnshot from cocos2d-JS
screenshot: function (fileName) {
var tex = new cc.RenderTexture(winSize.width, winSize.height, cc.Texture2D.PIXEL_FORMAT_RGBA8888);
tex.setPosition(cc.p(winSize.width / 2, winSize.height / 2));
tex.begin();
cc.director.getRunningScene().visit();
tex.end();
var imgPath = jsb.fileUtils.getWritablePath();
if (imgPath.length == 0) {
return;
}
var result = tex.saveToFile(fileName, cc.IMAGE_FORMAT_JPEG);
if (result) {
imgPath += fileName;
cc.log("save image:" + imgPath);
return imgPath;
}
return "";
}
then make a Java call from Javascript
public static void ScreenShot()
{
Bitmap imageBitmap = BitmapFactory.decodeFile(Cocos2dxHelper.getCocos2dxWritablePath() + "/" + "screenshot.png");
String fileHolder = "SampleFolder";
File filepathData = new File("/sdcard/" + fileHolder);
//~~~Create Dir
try {
if (!filepathData.exists())
{
filepathData.mkdirs();
filepathData.createNewFile();
FileWriter fw = new FileWriter(filepathData + fileHolder);
BufferedWriter out = new BufferedWriter(fw);
String toSave = String.valueOf(0);
out.write(toSave);
out.close();
}
}
catch (IOException e1) {
}
//~~~Create Image
File file = new File("/sdcard/" + "Your filename");
try
{
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
imageBitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
}
catch (Exception e) {}
Uri phototUri = Uri.fromFile(file);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, phototUri);
//~~~Add Code Below
}
Do not forget to add permission for external storage

The component cannot be found. (Exception from HRESULT: 0x88982F50) when setting stream to bitmapimage in windows phone 8 app

I am trying to add an element in existing isolated folder in xml
code:
public void writeToXML(List<AppTile> appList)
{
// Write to the Isolated Storage
XmlWriterSettings x_W_Settings = new XmlWriterSettings();
x_W_Settings.Indent = true;
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!ISF.FileExists("config.xml"))
{
using (IsolatedStorageFileStream stream = ISF.OpenFile("config.xml", FileMode.CreateNew))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<AppTile>));
using (XmlWriter xmlWriter = XmlWriter.Create(stream, x_W_Settings))
{
serializer.Serialize(xmlWriter, appList);
}
stream.Close();
}
}
else
{
string tileName = null;
string url = null;
string key = null;
byte [] tilePic = null;
XDocument loadedData;
if (appList != null)
{
foreach (AppTile app in appList)
{
tileName = app.TileName;
url = app.Url;
key = app.Key;
tilePic = app.TilePic;
// tilePic = Encoding.UTF8.GetString(app.TilePic,0,app.TilePic.Length);
// tilePic = Encoding.Unicode.GetString(app.TilePic,0,app.TilePic.Length);
// var writer = new BinaryWriter(tilePic);
}
using (Stream stream = ISF.OpenFile("config.xml", FileMode.Open, FileAccess.ReadWrite))
{
loadedData = XDocument.Load(stream);
var RootNode = new XElement("AppTile");
RootNode.Add(new XElement("TileName", tileName));
RootNode.Add(new XElement("Key", key));
RootNode.Add(new XElement("Url", url));
RootNode.Add(new XElement("TilePic", tilePic));
// Find Root Element And Descedents and Append New Node After That
var root = loadedData.Element("ArrayOfAppTile");
var rows = root.Descendants("AppTile");
var lastRow = rows.Last();
lastRow.AddAfterSelf(RootNode);
}
// Save To ISOconfig.xml File
using (IsolatedStorageFileStream newStream = new IsolatedStorageFileStream("config.xml", FileMode.Create, ISF))
{
loadedData.Save(newStream);
newStream.Close();
}
}
}
}
}
while reading from xml i am using xmlWriter and deserialize it to get List
when ever i am trying to acces the tilePic of AppTile type i am getting error :The component cannot be found. with the following code::
Image img = new Image();
MemoryStream imgStream = new MemoryStream(NewApp.TilePic);//NewApp is AppTile type
BitmapImage imgSource = new BitmapImage();
imgSource.SetSource(imgStream);//here i get error
img.Source = imgSource;
Its most likely with the TilePic i am saving is not formatted correctly to be retrieved.
Please Help!!
Why don't you use the SaveJpeg extension methodoogy in creating the byte array?
This one might help you!
Windows Phone - byte array to BitmapImage converter throws exception
solved the issue:
while saving the byte array it is encoded to some format not recognizable while reading,So what i have done is saved it as a string.So the updated code is:
else
{
string tileName = null;
string url = null;
string key = null;
string tilePicString = null;
XDocument loadedData;
System.Windows.Media.Imaging.BitmapImage imgSource = new System.Windows.Media.Imaging.BitmapImage();
if (appList != null)
{
foreach (AppTile app in appList)
{
tileName = app.TileName;
url = app.Url;
key = app.Key;
//changed here
tilePicString = System.Convert.ToBase64String(app.TilePic);
}
//same code as above