ITextsharp to edit existing pdf - winforms

I downloaded the pdf from the below link
http://ap.meeseva.gov.in/DeptPortal/Application%20Forms%20New/Revenue-pdf/Income%20General%20Application%20Form.pdf
What I need is I would like to fill out the blanks with the given text, I tried with the following code
using (FileStream outFile = new FileStream(#"E:\\residence(VRO)1.pdf", FileMode.Create))
{
PdfReader pdfReader = new PdfReader(#"E:\\residence(VRO).pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, outFile);
pdfStamper.FormFlattening = true;
AcroFields af = pdfReader.AcroFields;
string[] fields = pdfStamper.AcroFields.Fields.Select(x => x.Key).ToArray();
for (int key = 0; key <= fields.Count() - 1; key++)
{
}
}
But I am not getting the fields so can some one help me

The so-called form you refer to, isn't a form. That is: it's not an interactive form. I took that PDF and I added interactive fields. Please download adapted.pdf and examine it to discover the differences.
Now when you run your code on it, you'll see the fields, and you will be able to fill out the form with Western text. You are currently using iTextSharp 5 or earlier. That version of iText doesn't support Hindi. Hindi wasn't introduced up until iText 7. Hence if you want to fill out the form using an Indic writing system (Devanagari, Tamil,...), you need iText 7 for C# and the pdfCalligraph add-on. Note that the pdfCalligraph add-on is kept closed source. You need a commercial license to use it.
We kept that part closed source because:
Too many companies are using iText without respecting the AGPL license and without purchasing a license,
As far as I know, no other free software supports Indic writing systems. We'd be giving away too much value if we released pdfCalligraph as open source software.
Summarized:
your form is not a form. Make it a form.
use software that can fill out such a form using an Indic writing system (e.g. iText 7 + the pdfCalligraph add-on).

Related

Cannot Browse to specific Type in Settings designer for WPF/.net Core application

When I've used Settings Designer before, I've been able to browse to find non-standard Types (e.g. uncommon enums etc) to use in my Settings via a "Browse" button at the bottom of the drop down under the "Type" column. I'm developing a WPF desktop application for .net Core and there is no Browse option as pictured below:
I did go into the code behind (Settings.Designer.cs.) and edit the code manually, but on saving, this just reverted to string. I'm guessing this may have something to do with settings also having an element in App.config and I notice it has a "serialiseAs" tag - didn't know what to put here. Exmaple of the code behind settings and App.config:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string UiTheme {
get {
return ((string)(this["UiTheme"]));
}
set {
this["UiTheme"] = value;
}
}
<userSettings>
<GameBoxer.WPF.Properties.Settings>
<setting name="UiTheme" serializeAs="String">
<value />
</setting>
</GameBoxer.WPF.Properties.Settings>
</userSettings>
Does anyone know how to bring back the 'Browse'?? Or, how to correctly do it in code?
I'm using Visual Studio 2022 Community
Thanks
UPDATE: So, I learn that this is "By Design" in VS2022 according to MS here. It's still present in VS2019! But they've taken it out of VS2022 and I can't figure how to do it in code. MS, you're one of my faves out the bunch, but sometimes, you're as mad as a box of frogs. unfortunately that link doesn't provide the poster with any alternatives other than "that's not a bug." Not very helpful, really.
As mentioned in the link you provided, this change was by design due to .NET Core and while I very strongly disagree with their stance on this - I'm assuming this was done because it could be quite fiddly to get your own types to work as expected, especially for new users.
One simple workaround if your custom data has several values, you can use string and simply write your own little parser using delimiters such as ;. You could also use StringCollection to achieve the same result.
Inconvenient, yes. But a simple solution nonetheless.
I sincerely hope Microsoft changes their stance on this and looks at reimplementing this as it worked remarkably well once you figured out the procedure to get it to serialize properly.
Edit:
Figured I might as well provide an example;
// Storing the Settings
// Parameter: Struct { Location(Point), Size(Point), Margin(Thickness) }
var settingString = $"{e.Location.X};{e.Location.Y};{e.Size.X};{e.Size.Y};{e.Margin.Left};{e.Margin.Top};{e.Margin.Right};{e.Margin.Bottom}";
Properties.Settings.Default.MySetting = settingString;
Properties.Settings.Default.Save();
// Parsing the Saved Setting
var settingString = Properties.Settings.Default.MySetting;
if (!String.IsNullOrWhiteSpace(settingString))
{
List<string> splitStrings = settingString.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList();
List<double> parsedValues = new List<double>();
splitStrings.ForEach(x => parsedValues.Add(double.Parse(x)));
var location = new Point(parsedValues[0], parsedValues[1]);
var size = new Point(parsedValues[2], parsedValues[3]);
var margin = new Thickness(parsedValues[4], parsedValues[5], parsedValues[6], parsedValues[7]);
}
There's probably better ways of doing this, but I find this to be a very simple workaround and has worked great thus far.

How to Render Panel control to Pdf and Excel file in Windows form

This a Panel Control Contain Invoice Bill:
I want to make this Panel in Pdf and Excel file,but not in image format as a regular pdf file. This code is Written in Windows c#.
Graphics grp = panel.CreateGraphics();
Size formSize = this.ClientSize;
bitmap = new Bitmap(formSize.Width, 610, grp);
grp = Graphics.FromImage(bitmap);
Point panelLocation = PointToScreen(panel.Location);
grp.CopyFromScreen(panelLocation.X, panelLocation.Y, 0, 0, formSize);
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.PrintPreviewControl.Zoom = 1;
printPreviewDialog1.ShowDialog();
but it makes screen shot and create pdf file..
There is nothing that I know of that will take your image and create a "nice" PDF (small, searchable, zoomable) automatically. There is just too much room for error.
You will need to use something that is report-specific or pdf-specific to create your document. Depending on your requirements Docmosis and iText are good at this. Docmosis lets you build your layout in a doc template so it's easier than building in code, but it will still take work specific to the report you are creating. Please note I work for Docmosis. If you prefer a code-approach, iText is very good.
I hope that helps.

Missing MSDN documentation to develop xll add ins?

I spent quite a lot of time in looking for the full documentation of all the C API XLM Functions without success.
I found this page which illustrate a few of them:
http://msdn.microsoft.com/en-us/library/office/bb687910%28v=office.12%29.aspx
But for instance I wanted to understand and use xlfAddMenu, and I cannot find a page on MSDN that explain me.
Do you know if there is any documentation available? Apparently it is not so easy to get there.
There is no exhaustive official documentation for all C API XLM functions. However, as the documentation says following regarding C API XLM functions:
Many more functions are exposed by Excel via the C API that are useful
when you are developing XLLs. They correspond to the Excel worksheet
functions and functions and commands that are available from XLM macro
sheets."
Also, the EXAMPLE.[C,H] files which comme with the installation of the SDK use some of these functions and you can use it to learn how to use them. For instance, the xlfAddMenu is used in the xlAutoOpen callback function.
// In the following block of code, the Generic drop-down menu is created.
// Before creation, a check is made to determine if Generic already
// exists. If not, it is added. If the menu needs to be added, memory is
// allocated to hold the array of menu items. The g_rgMenu[] table is then
// transferred into the newly created array. The array is passed as an
// argument to xlfAddMenu to actually add the drop-down menu before the
// help menu. As a last step the memory allocated for the array is
// released.
//
// This block uses TempStr12() and TempNum12(). Both create a temporary
// XLOPER12. The XLOPER12 created by TempStr12() contains the string passed to
// it. The XLOPER12 created by TempNum12() contains the number passed to it.
// The Excel12f() function frees the allocated temporary memory. Both
// functions are part of the framework library.
Excel12f(xlfGetBar, &xTest, 3, TempInt12(10), TempStr12(L"Generic"), TempInt12(0));
if (xTest.xltype == xltypeErr)
{
hMenu = GlobalAlloc(GMEM_MOVEABLE,sizeof(XLOPER12) * g_rgMenuCols * g_rgMenuRows);
px = pxMenu = (LPXLOPER12) GlobalLock(hMenu);
for (i=0; i < g_rgMenuRows; i++)
{
for (j=0; j < g_rgMenuCols; j++)
{
px->xltype = xltypeStr;
px->val.str = TempStr12(g_rgMenu[i][j])->val.str;
px++;
}
}
xMenu.xltype = xltypeMulti;
xMenu.val.array.lparray = pxMenu;
xMenu.val.array.rows = g_rgMenuRows;
xMenu.val.array.columns = g_rgMenuCols;
Excel12f(xlfAddMenu,0,3,TempNum12(10),(LPXLOPER12)&xMenu,TempStr12(L"Help"));
GlobalUnlock(hMenu);
GlobalFree(hMenu);
}
According to me the best documentation (but not updated..) is the following book : Financial Applications using Excel Add-in Development in C / C++, 2nd Edition by Steve Dalton. You can find description of the xlfAddMenu function page 332. You can also find some useful information in the chm file of the Microsoft Excel XLL Software Development Kit, including codes examples (note I did not found the xlfAddMenu in it so I guess it is a depreciated function).

How to make a composite manifest for Microsoft smooth streaming

I am new to Microsoft Smooth Streaming and have questions about the making of composite manifests.
Following the guidance from here.
I was able to make a composite manifest of a single clip element that played in Silverlight player.
However, when I try to add more clips from other videos, the player stopped working and gave out no error information.
And I am doing this all by hand. and when I trying to use the Expression Encoder 4 Pro to create such a video, I got a normal .ismc file instead of a .csm file.
My questions are:
What is the best way of making a composite manifest which contains clips from different videos?
Is there any spec to follow when encoding these videos? or does the support of composite manifest put any restriction on the video format?
And the last one is: Is there an easy way to debug it (like validating my .csm file)?
EDIT my own solution:
Looks like no one cares about this, but since I finally solved this, I am writing this down here to save others' time.
to debug a composite manifest, I built a simple Silverlight app in Visual Studio, and add a simple function to report an error:
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
this.SmoothPlayer.SmoothStreamingErrorOccurred += new EventHandler<SmoothStreamingErrorEventArgs>(SmoothPlayer_SmoothStreamingErrorOccurred);
}
public void SmoothPlayer_SmoothStreamingErrorOccurred(object sender,
SmoothStreamingErrorEventArgs e)
{
MessageBox.Show("Error: " + e.ErrorCode + "; " + e.ErrorMessage);
}
And I found this web page useful.
You need to use:
<c t="", d"">
instead of
<c d="">
You have to calculate the ClipBegin and ClipEnd values right.
Below is a sample code in python to convert a .ismc to a .csm(assume that the ism below is an xml.etree.ElementTree object representation of the manifest xml content):
def ism2csm(url, ism):
if ism is None: return csm
csm = xml.Element('SmoothStreamingMedia', {'MajorVersion':'2', 'MinorVersion':'1', 'Duration':ism.attrib.get('Duration')})
clip = xml.Element('Clip', {'Url':url, 'ClipBegin':'0','ClipEnd':'0'})
csm.append(clip)
for stream_index in ism.iter('StreamIndex'):
clip.append(stream_index)
for stream_index in clip.iter('StreamIndex'):
t = 0
last_c = None
for c in stream_index.iter('c'):
c.attrib['t'] = str(t)
t += int(c.attrib.get('d'))
if last_c is not None: del last_c.attrib['d']
last_c = c
if clip.attrib.get('ClipEnd') == '0':
clip.attrib['ClipEnd'] = str(t)
return csm

How to export Rich Text fields as HTML from Notes with LotusScript?

I'm working on a data migration task, where I have to export a somewhat large Lotus Notes application into a blogging platform. My first task was to export the articles from Lotus Notes into CSV files.
I created a Agent in LotusScript to export the data into CSV files. I use a modified version of this IBM DeveloperWorks forum post. And it basically does the job. But the contents of the Rich Text field is stripped of any formatting. And this is not what I want, I want the Rich Text field rendered as HTML.
The documentation for the GetItemValue method explicitly states that the text is rendered into plain text. So I began to research for something that would retrieve the HTML. I found the NotesMIMEEntity class and some sample code in the IBM article How To Access HTML in a Rich Text Field Using LotusScript.
But for the technique described in the above article to work, the Rich Text field need to have the property "Store Contents as HTML and MIME". And this is not the case with my Lotus Notes database. I tried to set the property on the fields in question, but it didn't do the trick.
Is it possible to use the NotesMIMEEntity and set the "Store Contents as HTML and MIME" property after the content has been added, to export the field rendered as HTML?
Or what are my options for exporting the Notes database Rich Text fields as HTML?
Bonus information: I'm using IBM Lotus Domino Designer version 8.5
There is this fairly unknown command that does exactly what you want: retrieve the URL using the command OpenField.
Example that converts only the Body-field:
http://SERVER/your%5Fdatabase%5Fpath.nsf/NEW%5FVIEW/docid/Body?OpenField
Here is how I did it, using the OpenField command, see D.Bugger's post above
Function GetHtmlFromField(doc As NotesDocument, fieldname As String) As String
Dim obj
Set obj = CreateObject("Microsoft.XMLHTTP")
obj.open "GET", "http://www.mydomain.dk/database.nsf/0/" + doc.Universalid + "/" + fieldname + "?openfield&charset=utf-8", False, "", ""
obj.send("")
Dim html As String
html = Trim$(obj.responseText)
GetHtmlFromField = html
End Function
I'd suggest looking at Midas' Rich Text LSX (http://www.geniisoft.com/showcase.nsf/MidasLSX)
I haven't used the personally, but I remember them from years ago being the best option for working with Rich Text. I'd bet it saves you a lot of headaches.
As for the NotesMIMEEntity class, I don't believe there is a way to convert RichText to MIME, only MIME to RichText (or retain the MIME within the document for emailing purposes).
If you upgrade to Notes Domino 8.5.1 then you can use the new ConvertToMIME method of the NotesDocument class. See the docs. This should do what you want.
Alternativly the easiest way to get the Domino server to render the RichText will be to actually retrieve it via a url call. Set up a simple form that just has the RichText field and then use your favourite HTTP api to pull in the page. It should then be pretty straight forward to pull out the body.
Keep it simple.
Change the BODY field to Store contents as HTML and MIME
Open the doc in editmode.
Save.
Close.
You can now use the NotesMIMEEntity to get what you need from script.
You can use the NotesDXLExporter class to export the Rich Text and use an XSLT to transform the output to what you need.
I know you mentioned using LotusScript, but if you don't mind writing a small Java agent (in the Notes client), this can be done fairly easily - and there is no need to modify the existing form design.
The basic idea is to have your Java code open a particular document through a localhost http request (which is simple in Java) and to have your code capture that html output and save it back to that document. You basically allow the Domino rendering engine to do the heavy lifting.
You would want do this:
Create a form which contains only the rich-text field you want to convert, and with Content Type of HTML
Create a view with a selection formula for all of the documents you want to convert, and with a form formula which computes to the new form
Create the Java agent which just walks your view, and for each document gets its docid, opens a URL in the form http://SERVER/your_database_path.nsf/NEW_VIEW/docid?openDocument, grabs the http response and saves it.
I put up some sample code in a similar SO post here:
How to convert text and rich text fields in a document to html using lotusscript?
Works in Domino 10 (have not tested with 9)
HTMLStrings$ = NotesRichTextItem .Converttohtml([options] ) As String
See documentation :
https://help.hcltechsw.com/dom_designer/10.0.1/basic/H_CONVERTOHTML_METHOD_NOTESRICHTEXTITEM.html
UPDATE (2022)
HCL no longer support this method since version 11. The documentation does not include any info about the method.
I have made some tests and it still works in v12 but HCL recommended to not use it.
Casper's recommendation above works well, but make sure the ACL is such to allow Anonymous Access otherwise your HTML will be the HTML from your login form
If you do not need to get the Richtext from the items specifically, you can use ?OpenDocument, which is documented (at least) here: https://www.ibm.com/developerworks/lotus/library/ls-Domino_URL_cheat_sheet/
https://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/com.ibm.designer.domino.main.doc/H_ABOUT_URL_COMMANDS_FOR_OPENING_DOCUMENTS_BY_KEY.html
OpenDocument also allows you to expand sections (I am unsure if OpenField does)
Syntax is:
http://Host/Database/View/DocumentUniversalID?OpenDocument
But be sure to include the charset parameter as well - Japanese documents were unreadable without specifying utf-8 as the charset.
Here is the method I use that takes a NotesDocument and returns the HTML for the doc as a string.
private string ConvertDocumentToHml(Domino.NotesDocument doc, string sectionList = null)
{
var server = doc.ParentDatabase.Server.Split('/')[0];
var dbPath = doc.ParentDatabase.FilePath;
string viewName = "0";
string documentId = doc.UniversalID.ToUpper();
var ub = new UriBuilder();
ub.Host = server;
ub.Path = dbPath.Replace("\\", "/") + "/" + viewName + "/" + documentId;
if (string.IsNullOrEmpty(sectionList))
{
ub.Query = "OpenDocument&charset=utf-8";
}
else
{
ub.Query = "OpenDocument&charset=utf-8&ExpandSection=" + sectionList;
}
var url = ub.ToString();
var req = HttpWebRequest.CreateHttp(url);
try
{
var resp = req.GetResponse();
string respText = null;
using (var sr = new StreamReader(resp.GetResponseStream()))
{
respText = sr.ReadToEnd();
}
return respText;
}
catch (WebException ex)
{
return "";
}
}

Resources