Developer Tools
|
Office Productivity Applications
|
Platform-Agnostic APIs
|
Home | Online Demos | Downloads | Buy Now | Support | About Us | News | Working Together | Contact Us
The move from PCs to tablets seems unstoppable now. People are abandoning their laptops and desktops and prefer to work with cool IOS and Android tablets. Due to the limitations of battery technology, tablets cannot run apps with the same resource-load as traditional PC applications. For this reason, IT departments all over the world are moving their desktop applications to centralized servers (or "the cloud," as they like to call it). These server-side applications are then accessed from tablets via lightweight frontend applications - either dedicated tablet apps or run-anywhere browser-based Web applications.
In this article, I will use the example of a desktop application written using eDocEngine and then show you how to move it to a server. I will also demonstrate how to provide access to the server application using a frontend Web application. (I have chosen ASP.NET but you can choose your existing Web development platform.)
Here is an application built with eDocEngine and TRichView. It allows the end-user to select an RTF document and then the application will convert the document to PDF.
// Allow the end-user to select a RTF document // and display it procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.Execute then begin RichView1.Style := RVStyle1; RichView1.LoadRTF(OpenDialog1.FileName); RichView1.Format; Button2.Enabled := True; end; end; // Export the displayed RTF document to PDF procedure TForm1.Button2Click(Sender: TObject); begin gtPDFEngine1.FileName := 'converted_doc.pdf'; gtPDFEngine1.Page.TopMargin := 1; gtPDFEngine1.Page.RightMargin := 1; gtPDFEngine1.Page.BottomMargin := 1; gtPDFEngine1.Page.LeftMargin := 1; gtRichViewInterface1.Engine := gtPDFEngine1; RVReportHelper1.RichView.Style := RVStyle1; RVReportHelper1.RichView.LoadRTF(OpenDialog1.FileName); gtRichViewInterface1.RenderDocument(RVReportHelper1); RVReportHelper1.Clear; end;
If you wish to provide a similar service to tablet users or remote workers, then you need to create a frontend application for them to upload their RTF documents. So, here is sample Web application. You can open it from any device that can run a HTML Web browser.
This ASP.NET application accepts the e-mail address and the RTF file from the end-user. The RTF document is saved to a writable "Uploads" folder under App_Data. It also prefixes the end-user's email address and a custom delimiter to the uploaded file name. (This saves me the hassle of storing all the data in a database.)
Delphi Prism (Oxygene) | C# |
---|---|
method _Default.Button1_Click(sender: System.Object; e: System.EventArgs); var sExtension: String; begin if (TextBox1.Text.Length > 4) then begin if (FileUpload1.HasFile) then begin sExtension := Path.GetExtension(FileUpload1.FileName).ToLower; if (sExtension = ".rtf") then begin FileUpload1.SaveAs(Server.MapPath("~/App_Data/Uploads/" + TextBox1.Text + " ~~@~~ " + FileUpload1.FileName)); Label1.Text := 'Thank you. Your documented will be converted to PDF and mailed to you.'; end else begin Label1.Text := 'Your files does not look like an RTF document.'; end; end else begin Label1.Text := 'You did not select a file.'; end; end else begin Label1.Text := 'You did not select a file.'; end; end; end; |
|
protected void Button1_Click(object sender, EventArgs e) { String sExtension; if (TextBox1.Text.Length > 4) { if (FileUpload1.HasFile) { sExtension = Path.GetExtension(FileUpload1.FileName).ToLower(); if (sExtension == ".rtf") { FileUpload1.SaveAs(Server.MapPath("~/App_Data/Uploads/" + TextBox1.Text + " ~~@~~ " + FileUpload1.FileName)); Label1.Text = "Thank you. Your documented will be converted to PDF and mailed to you."; } else { Label1.Text = "Your files does not look like an RTF document."; } } else { Label1.Text = "You did not select a file"; } } else { Label1.Text = "You did not enter a valid e-mail address."; } } |
That takes care of the frontend. Now, let us port our eDocEngine application to the server.
While it is possible to convert the RTF document to PDF from within the ASP.NET application (so that user can upload RTF and download PDF), I did not choose that route. If the input RTF document is very big, then conversion can take too long. There is no point in keeping the user waiting. Also, a web page request is expected to finish execution in a fraction of a second, if not whole seconds. When that does not happen, IIS (or whichever web server software your Web application is running on) will kill that request. Web server software will not let a single user hog the server or a handful of users overwhelm it.
"Upload RTF, download PDF" can still be accomplished if you can link your webserver with an application server or a farm of application servers that can take over the actual conversion. After the upload, the Web application can serve a page with a Javascript script that asynchronously requests a unique URL to see if the converted document is available for download. Meanwhile, you can show a "Please wait. Converting…" message accompanied with a rotating hourglass animation. If properly set up, you can create the illusion of almost no waiting time.
An alternative is to run a Windows service on the Web server that does the actual conversion. A big advantage of a Windows service is that it does not suffer from the limitations that the Web application sandbox - short lifecycle, limited security permissions, exposure to attacks from outsiders, etc.
A Windows service can watch the upload folder and perform the conversion when it finds a RTF document. After the conversion, the service can also e-mail the PDF document to the end-user. Here is how:
StrUtils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdAttachment, IdExplicitTLSClientServerBase, IdMessageClient, IdSMTPBase, IdSMTP, IdMessage, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdMessageParts;(I am using Indy with eDocEngine for mailing the converted documents.)
LogFilePath: string; LogFile: TextFile; UploadFolderPath: string; OutputFolderPath: string;
OnStart
event.
procedure TLazy_RTF_2_PDF_Converter.ServiceStart(Sender: TService; var Started: Boolean); begin // Location of the log file LogFilePath := 'I:\2012_05_14_EV_SAS\sas.log'; // RTF upload folder that needs to be watched UploadFolderPath := 'I:\2012_03_30_SAS\App_Data\Uploads\'; // Folder where the PDF file needs to be created OutputFolderPath := 'I:\2012_05_14_EV_SAS\'; if not FileExists(LogFilePath) then begin AssignFile(LogFile, LogFilePath); Rewrite(LogFile); CloseFile(LogFile); end; end;In this procedure, modify the variables with paths from your computer.
OnTimer
event. This procedure will ensure
that the service regularly checks (that is, every 30 seconds) the upload folder
for RTF documents and convert them. The procedure also deletes the RTF
file after it has been converted and mailed out.
procedure TLazy_RTF_2_PDF_Converter.Timer1Timer(Sender: TObject); var SearchRec1: TSearchRec; MessagePart1: TIdMessagePart; begin UpdateLog('Finding uploads...'); if FindFirst(UploadFolderPath + '*.*', faArchive, SearchRec1) = 0 then begin UpdateLog('File found. Checking for file locks...'); if IsFileInUse(UploadFolderPath + SearchRec1.Name) = False then begin if RightStr(LowerCase(SearchRec1.Name),3) = 'rtf' then begin UpdateLog('Found an RTF file' + SearchRec1.Name + '. Converting it...'); ConvertRTF2PDF(UploadFolderPath, SearchRec1.Name); end; UpdateLog('Deleting ' + SearchRec1.Name); DeleteFile(UploadFolderPath + SearchRec1.Name); end; end; end;The
ConvertRTF2PDF
method referred by this procedure
does the same job as in the sample desktop
application referred earlier. It does some additional work -
identifying the e-mail address and the original file name, and then
mailing the converted document to the uploader. It also logs operations
and errors to a log file.
ConvertRTF2PDF
and rest of the code.
procedure TLazy_RTF_2_PDF_Converter.ConvertRTF2PDF(AFilePath, AFileName: string); var sPathName: string; begin sPathName := AFilePath + AFileName; gtPDFEngine1.FileName := OutputFolderPath + CatchFileName(AFileName); UpdateLog('About convert to ' + gtPDFEngine1.FileName + '.pdf'); gtPDFEngine1.Preferences.ShowSetupDialog := False; gtPDFEngine1.Preferences.OpenAfterCreate := False; // Enable automatic e-mailing of converted documents gtPDFEngine1.Preferences.EmailAfterCreate := True; with gtPDFEngine1.EMailSettings do begin Host := 'smtp.example.com'; UserID := 'user@example.com'; Password := 'secret'; Port := 25; AuthenticationRequired := True; Subject := 'Season''s greeting'; Body.Clear; Body.Add('Hi,' + Chr(10) + Chr(10) + 'PFA.'); FromName := 'It''s Me'; FromAddress := 'joe@example.com'; RecipientList.Clear; RecipientList.Add(CatchEmailAddress(AFileName)); end; try // Add default page margins gtPDFEngine1.Page.TopMargin := 1; gtPDFEngine1.Page.RightMargin := 1; gtPDFEngine1.Page.BottomMargin := 1; gtPDFEngine1.Page.LeftMargin := 1; // Set output PDF file name for the engine gtRichViewInterface1.Engine := gtPDFEngine1; RVReportHelper1.RichView.Style := RVStyle1; UpdateLog('Loading ' + sPathName); // Load a RTF document with a report helper component RVReportHelper1.RichView.LoadRTF(sPathName); UpdateLog('Rendering ' + sPathName); // Render PDF using the print output gtRichViewInterface1.RenderDocument(RVReportHelper1); UpdateLog('Clearing memory'); // Free memory RVReportHelper1.Clear; RVReportHelper1.RichView.Clear; except on Err: Exception do begin UpdateLog(Err.Message); end; end; end; function TLazy_RTF_2_PDF_Converter.CatchEmailAddress(AFileName: string): string; var n: Integer; begin n := Pos(' ~~@~~ ', AFileName); Result := LeftStr(AFileName, n) end; function TLazy_RTF_2_PDF_Converter.CatchFileName(AFileName: string): string; var n: Integer; sFileName: string; begin if Length(AFileName) > 4 then begin n := Length(AFileName) - Pos('~~@~~', AFileName) - Length('~~@~~'); sFileName := RightStr(AFileName, n); Result := LeftStr(sFileName, Length(sFileName) - 4); end; end; function TLazy_RTF_2_PDF_Converter.IsFileInUse( Const FileName: String ): Boolean; var HFileRes: HFILE; begin Result := False; If not FileExists( FileName ) then Exit; HFileRes := CreateFile( PChar( FileName ), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); Result := ( HFileRes = INVALID_HANDLE_VALUE ); If not Result then CloseHandle( HFileRes ); end; procedure TLazy_RTF_2_PDF_Converter.UpdateLog(AEntry: string); begin AssignFile(LogFile, LogFilePath); Append(LogFile); Writeln(LogFile, DateTimeToStr(Now) + ': ' + AEntry); CloseFile(LogFile); end;
ConvertRTF2PDF
procedure, modify the
EMailSettings
property of the PDF engine so that
it works with your SMTP server./install
switch.
/uninstall
switch.)services.msc
in the Windows Run dialog box.Note: If you are testing this code, then remember to stop and uninstall the service when you are finished with it.
---o0O0o---
Our .NET Developer Tools | |
---|---|
![]() Gnostice Document Studio .NETMulti-format document-processing component suite for .NET developers. |
![]() PDFOne .NETA .NET PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, and bookmark PDF documents in .NET applications. |
Our Delphi/C++Builder developer tools | |
---|---|
![]() Gnostice Document Studio DelphiMulti-format document-processing component suite for Delphi/C++Builder developers, covering both VCL and FireMonkey platforms. |
![]() eDocEngine VCLA Delphi/C++Builder component suite for creating documents in over 20 formats and also export reports from popular Delphi reporting tools. |
![]() PDFtoolkit VCLA Delphi/C++Builder component suite to edit, enhance, view, print, merge, split, encrypt, annotate, and bookmark PDF documents. |
Our Java developer tools | |
---|---|
![]() Gnostice Document Studio JavaMulti-format document-processing component suite for Java developers. |
![]() PDFOne (for Java)A Java PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, bookmark PDF documents in Java applications. |
Our Platform-Agnostic Cloud and On-Premises APIs | |
---|---|
![]() StarDocsCloud-hosted and On-Premises REST-based document-processing and document-viewing APIs |
Privacy | Legal | Feedback | Newsletter | Blog | Resellers | © 2002-2025 Gnostice Information Technologies Private Limited. All rights reserved. |