iTextSharp - MVC / HTMLWorker one string to add to a paragraph - asp.net

I am sending the contents of Telerik MVC Editor to the controller using Ajax as a string:
I comes out as:
"<strong>Hello world!</strong> <object height=\"1\" id=\"plugin0\" style=\"position:absolute;z-index:1000;\" type=\"application/x-dgnria\" width=\"1\"><param name=\"tabId\" value=\"{84594B7B-865F-4AD7-A798-294A8B0EB376}\" /></object>"
In the controller, I save the string to a session variable using the following:
string comments = HttpUtility.HtmlDecode(Text);
MySession.Current.pdfText = comments;
I can convert it to PDF using
.....
HTMLWorker parser = new HTMLWorker(document);
.......
However I could not add any other paragraphes to the same page, it makes a new page.
I tried to use the following to make a new paragraph using HTMLWORK:
string PDFText = MySession.Current.pdfText;
string PDFText1 = HTMLWorker.Parse(PDFText);
StringReader reader = new StringReader(PDFText1);
paragraph.Add(reader);
I got these errors:
cannot convert from 'System.IO.StringReader' to 'string', and
The best overloaded method match for 'iTextSharp.text.html.simpleparser.HTMLWorker.Parse(System.IO.TextReader)' has some invalid arguments, and
The best overloaded method match for 'iTextSharp.text.Phrase.Add(string)' has some invalid arguments
I would appreciate your suggestions, thanks in advance.

I have worked a lot on iTextSharp and I usually follow the approach of creating a table or nested tables; if needed, with multiple rows and columns and using colspan to spread out my content on the page.
PdfPTable table = new PdfPTable(1); //Create a new table with one column
PdfPCell cell = new PdfPCell(); //Create an empty cell
StyleSheet style = new StyleSheet(); //Declare a stylesheet
style.LoadTagStyle("h1", "color", "red"); //Create styles for your html tags which you think will be there in PDFText
ArrayList objects = HTMLWorker.ParseToList(new StringReader(PDFText),style); //This transforms your HTML to a list of PDF compatible objects
for (int k = 0; k < objects.Count; ++k)
{
cell.AddElement((IElement)objects[k]); //Add these objects to cell one by one
}
table.AddCell(cell); //Add cell to table
document.add(table) //Add table to the document
try it out with just the paragraph once as you were trying in the question. otherwise this approach will definitely not result in a new page.
EDIT:
please see the updated code
PdfPTable table = new PdfPTable(2); //Create a new table with one column
PdfPCell cellLeft = new PdfPCell(); //Create an empty cell
StyleSheet style = new StyleSheet(); //Declare a stylesheet
style.LoadTagStyle("h1", "color", "red"); //Create styles for your html tags which you think will be there in PDFText
List<IElement> objects = HTMLWorker.ParseToList(new StringReader(PDFText),style); //This transforms your HTML to a list of PDF compatible objects
for (int k = 0; k < objects.Count; ++k)
{
cellLeft.AddElement((IElement)objects[k]); //Add these objects to cell one by one
}
table.AddCell(cellLeft); //Add cell to table
string url = "http://localhost:1713/PDF/Images/sample.jpg"; //Image Path(can give local machine path for testing)
PdfPCell cellRight = new PdfPCell();
Image jpg = Image.GetInstance(new Uri(url));
cellRight.AddElement(jpg);
table.AddCell(cellRight);
document.add(table);
Please google for padding, margins, borders and coloring etc..

Related

How to get the selected value from a dropdown in MVC to use inside the view

I have an MVC app with leaflet running in it, I am parsing xml data to get the paths to the leaflet tiles which I then display in a drop down via a ViewData["value"]. The problem is I can't seem to figure out how to get that selected value and pass it down to the leaflet js as a path and then display everything. I tried many different ways to get the selection data but I'm just hitting a wall again and again.
The below code is how I send it to the view. I display it via an #Html.DropDownList("layerType", ViewData["value"] as List)
string outputPath;
outputPath = ConfigurationManager.AppSettings.Get("outputPath");
XmlDocument xDoc = new XmlDocument();
xDoc.Load(outputPath + #"\log.xml");
XmlNodeList layerType = xDoc.GetElementsByTagName("layerType");
XmlNodeList layerPath = xDoc.GetElementsByTagName("layerPath");
XDocument doc = XDocument.Load(outputPath + #"\log.xml");
var count = doc.Descendants("layers")
.Descendants("layerData")
.Count();
List<SelectListItem> li = new List<SelectListItem>();
foreach (int i in Enumerable.Range(0, count))
{
li.Add(new SelectListItem { Text = layerPath[i].InnerText, Value = i.ToString() });
}
ViewData["value"] = li;
return View(li);
How would I get the selected data and simply pass it down into the leaflet part inside the js tags.
Would I maybe pass it back into a controller and then back to the view?
#Html.DropDownList("layerType",
new SelectList((IEnumerable) ViewData["value"]), "Value", "Text")
In the Post method, you have to fill the viewdata again to avoid error if model returns invalid
Refer Below Link :
MVC Select List with Model at postback, how?
Working Code
https://dotnetfiddle.net/2lrb2S
Get Value on View
<script>
var conceptName = $('#nameofyourdropdowncontrol').find(":selected").text();
//code for passing value
</script>

Flex 3: dynamically created checkbox column in datagrid - data population issues and event listener

I have a datagrid control in my mxml file:
Now in my AS file, in the result function when obtaining data from DB, I can create columns dynamically. Let's say I create 1 column (client name):
private function GetDebtors_Result(event:ResultEvent):void
{
var arrayCol:Array = new Array();
var xmlSrc:XML = new XML("<main></main>");
var xmlTmp:XML;
var colClientname:DataGridColumn;
//Build an XML from DB data received (could as well use "event.result" directly to act as dataprovider for the datagrid, but I needed to break it down here)
for each(var o:Object in event.result)
{
xmlTmp = <row>
<CLIENTNAME>{o.CLIENTNAME}</CLIENTNAME>
</row>;
xmlSrc.appendChild(xmlTmp);
}
//Create the column CLIENTNAME
colClientname = new DataGridColumn("CLIENTNAME");
colClientname.headerText = "Client Name";
//Add the newly created column in the "Column" array.
arrayCol.push(colClientname);
//Use the "Column" array to set the columns of the datagrid.
dgSearch.columns = arrayCol;
//Populate the datagrid with the XML data.
dgSearch.dataProvider = xmlSrc.row;
}
This works well.
Now comes the issue: I need to add a second column which will contain checkboxes. They will be selected or deselected depending on the data from database. I'll show how I've done it by updating the same "GetDebtors_Result" function as above (added lines are commented as "// ADDED"):
private function GetDebtors_Result(event:ResultEvent):void
{
var arrayCol:Array = new Array();
var xmlSrc:XML = new XML("<main></main>");
var xmlTmp:XML;
var colClientname:DataGridColumn;
var colSel:DataGridColumn; // **ADDED**
//Build an XML from DB data received (could as well use "event.result" directly to act as dataprovider for the datagrid, but I needed to break it down here)
for each(var o:Object in event.result)
{
xmlTmp = <row>
<CLIENTNAME>{o.CLIENTNAME}</CLIENTNAME>
<SELECTED>{(o.SELECTED == 1)?true:false}</SELECTED> //**ADDED**
</row>;
xmlSrc.appendChild(xmlTmp);
}
//Create the column CLIENTNAME
colClientname = new DataGridColumn("CLIENTNAME");
colClientname.headerText = "Client Name";
//Create the column SELECTED
colSel = new DataGridColumn("SELECTED"); // **ADDED**
colSel.headerText = ""; // **ADDED**
colSel.itemRenderer = new ClassFactory(mx.controls.CheckBox); // **ADDED**
colSel.dataField = "SELECTED"; // **ADDED**
//Add the newly created column in the "Column" array.
arrayCol.push(colClientname);
//Add the "selection" column in the "Column" array.
arrayCol.push(colSel); // **ADDED**
//Use the "Column" array to set the columns of the datagrid.
dgSearch.columns = arrayCol;
//Populate the datagrid with the XML data.
dgSearch.dataProvider = xmlSrc.row;
}
Problem #1: The checkbox column appears, I can check and uncheck the checkboxes, but they are not checked/unchecked respective to DB data when loaded.
Problem #2: How do I associate a function to the checkboxes, for instance one which will update the XML so that I can save the new data to the DB?
Anybody got the solution? Thank you in advance.
Seems to be a very old question that I saw today.
Hopefully you would have found out the solution by now, just in-case if anyone has same problem:
While adding a checkbox to column- just instantiate it 1st:
var chkTempCheck: Checkbox = new CheckBox();
Then set all the properties required:
chkTempCheck.selected = o.dBColumnToDecideCheckUnCheck
here 'o' is the Object you are using from event.result.
This will work for sure!
The initial scenario was: all columns were defined in the mxml file. The checkbox column used itemrenderer and was working properly. I was using the same datagrid in 3 different cases - only thing was that some columns were set visible/invisible depending on the 'views'. The problem was when shifting 'views' and populate the grid and shift 'views' again, the column widths kept increasing exponentially. I excluded the checkbox column and everything worked fine; columns widths were ok. I included the checkbox column back and tried setting the column widths in AS file and the column-increasing-exponentially problem was fixed but the column widths were never the same when populating grid in view A and when populating grid in view B. ...So I ventured out in trying to set the columns in AS file just after obtaining DB data. Hope you can find yourself in those situations. Thanks for helping.

How to covert a flex datagrid with XMLList dataprovider to pdf using AlivePDF?

My flex data grid has a XMLListCollection as its data provider.
AlivePDF's Grid expects data grid's data provider to be an array.
Is there a way to PDF this table without going through each and every XML node and populating an array of objects to feed to AlivePDF's Grid?
Are there any other better solutions that I can try out to covert this table to PDF?
Thanks!
ListCollectionView (XMLListCollection base class) has toArray() method
So, just new Grid(dataProvider.toArray(),...)
Here is a sample code snippet that may help you :
Here dataGrid has 2 columns. And chilledWaterLoopXml is the xml containing the data..
var gridColumnFirstcol:GridColumn = new GridColumn('Design ΔT','designDelta', 40, Align.LEFT, Align.LEFT);
var gridColumnSecondcol:GridColumn = new GridColumn('Chilled Water', 'chilledWtrPump', 40, Align.LEFT, Align.LEFT);
var result:ArrayCollection=new ArrayCollection();
for(var i:int =0;i<chilledWaterLoopXml.children().length();i++)
{
var resultant:Object = new Object();
resultant["designDelta"]=chilledWaterLoopXml.child(i).designDelta;
resultant["chilledWtrPump"]=chilledWaterLoopXml.child(i).chilledWtrPump;
result.addItem(resultant);
}
var grid:org.alivepdf.data.Grid = new org.alivepdf.data.Grid( result.toArray() , 100,50, new RGBColor(0xD4CCC5), new RGBColor(0x66C66C),0, new RGBColor(0x000000),1,Joint.ROUND);
grid.columns = columns;
pdf.addGrid(grid);

How to align cell vertically with RowSpan>1

I want to have this ,
but instead have this .
Please note, when I change VerticalAlign.Middle to VerticalAlign.Top it actually works as expected.
Please see below code that I am trying:
// I assume that table table is already created and well-defined
// Create a new row
TableRow tRow = new TableRow();
tRow.HorizontalAlign = HorizontalAlign.Center;
// add the row to the table
table.Rows.Add(tRow);
// Create a new cell
TableCell tCell = new TableCell();
tCell.VerticalAlign = VerticalAlign.Middle; // Want to get it in the middle of two merged rows
tCell.RowSpan = 2;
tCell.Text = "England";
tCell.Font.Bold = true;
tRow.Cells.Add(tCell);
// Create new cell
tCell = new TableCell();
tCell.Text = "2010";
tCell.Font.Bold = true;
tRow.Cells.Add(tCell);
// Create new row
tRow = new TableRow();
// add the row to the table
table.Rows.Add(tRow);
// Create new cell
tCell = new TableCell();
tCell.Text = "2011";
tCell.Font.Bold = true;
tRow.Cells.Add(tCell);
Update: Please see extra code below. I don't have html code as such, but I looked at sw.ToString() and formatting looks right but still excel file does not seem to be rightly formatted. My browser is IE but I think it does not matter.
I tried tCell.CssClass = "className"; result is the same.
public static void Comparison_Report(string fileName)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName));
HttpContext.Current.Response.ContentType = "application/ms-excel";
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// Create a table to contain the grid
Table table = new Table();
///----- Original code goes here----
// render the table into the htmlwriter
table.RenderControl(htw);
// render the htmlwriter into the response
HttpContext.Current.Response.Write(sw.ToString());
HttpContext.Current.Response.End();
}
}
}
Finally i've tested it by myself. It seems not to work in Excel if you use valign="middle" on your table-cell. You must use CSS.
So instead of
tCell.VerticalAlign = VerticalAlign.Middle
do
tCell.Style.Add("vertical-align", "middle")
That will align the text correctly in excel. Excel itself uses css-classes if you export it from excel to html.
But repeating my comment, i would recommend to generate a real excel file instead of creating html that might be openened and interpreted correctly.
It's very simple with EPPlus: Exporting data to excel
Do this in CSS please!! Set a class on the cell that you want to have 'England' in it and target that class.
Code
tCell.Text = "England";
tCell.CssClass = "className";
Css
td.className {
vertical-align:middle;
}
Edit
Ok so by popular demand an explanation for why to use CSS here rather than set this in the creation of the table cell.
What you gain from using a seperate stylesheet is a whole heap of power and control on how this element is going to look on the client. When you set this in code you are explicitly saying it should only be like this - however when you set it in CSS and use a stylesheet you can do things like target different platforms, change the position easily, add extra elements etc. This is the old discussion between having inline style and pulling the style out into a separate sheet. I think this topic is quite well discussed on the web if you care to read more about it...
Edit 2
I just tried your code as you pasted it and it worked fine for me - the cell was middle aligned. I would use Firebug to try figure out if there are some other styles that are acting on that table cell to make it have this behavior.
<td align='left' valign='middle' ></td>
Not working in exporting excel file from code behind.so i search in internet and found this example.
td.className {
vertical-align:middle;
}
this save my time.
Thanks

Flex BitmapData.draw() only draws a white rectangle -- can I draw all elements of a display object?

I am trying to save a component as a JPG file and I can't seem to get the BitmapData.draw() to give me the pixels I'm expecting and instead I am seeing a plain white rectangle when I open the resulting JPG file. I am first creating an object which contains an image and a caption (the MultigraphCanvas below) and when I display the object as a pop up it looks perfect -- however when I try to draw it as a bitmap and then encode and save it as a JPG I don't end up with the same image I can display on the screen. Here's the code:
private function saveAsFile(title:String):void
{
// make a canvas containing the multigraph and title
var multigraphCanvas:MultigraphCanvas = new MultigraphCanvas();
multigraphCanvas.initialize();
multigraphCanvas.multigraphGroup = multigraphGroup;
multigraphCanvas.titleText.text = title;
this.addElement(multigraphCanvas);
var matrix:Matrix = new Matrix()
matrix.tx = 0;
matrix.ty = 0;
var multigraphCanvasBitmapData:BitmapData = new BitmapData(multigraphCanvas.width, multigraphCanvas.height, true, 0xffffffff);
multigraphCanvasBitmapData.draw(multigraphCanvas, matrix);
var multigraphCanvasImage:Image = new Image();
multigraphCanvasImage.load(new Bitmap(multigraphCanvasBitmapData));
multigraphCanvasImage.content.width = multigraphCanvas.width;
multigraphCanvasImage.content.height = multigraphCanvas.height;
var multigraphCanvasImageBitmapData:BitmapData = new BitmapData(multigraphCanvas.width, multigraphCanvas.height, true, 0xffffffff);
multigraphCanvasImageBitmapData.draw(multigraphCanvasImage);
// DEBUGGING
PopUpManager.addPopUp(multigraphCanvas, this);
// DEBUGGING
var debugImage:Image = new Image();
debugImage.source = multigraphCanvasImageBitmapData;
var debugTitleWindow:TitleWindow = new TitleWindow();
debugTitleWindow.addElement(debugImage);
PopUpManager.addPopUp(debugTitleWindow, this);
// encode the canvas bitmap into a JPG byte array
var jpgEncoder:JPEGEncoder = new JPEGEncoder(85);
var jpgByteArray:ByteArray = jpgEncoder.encode(multigraphCanvasImageBitmapData);
// save the JPG byte array as a file
var fileReference:FileReference = new FileReference();
fileReference.save(jpgByteArray, title + ".jpg");
}
Can I expect for the BitmapData.draw() method to draw each component of the display object it's passed, or does it just render the topmost element and none of the children (this is what it looks like to me)?
I believe that components need to be in the display tree for BitmapData.draw() to be able to render them.
I have been up for the last 24 hours so if the function is broke don't blame me :)
This is a stripped down version of a function I have that takes a snapshot of the container(c1) and sends it off to the server. I was base64 encoding as that was what the Java guy wanted for the back-end. You will have to massage the setting for your needs. I cut out a lot of the stuff I had in this function
private function getSnapShot( e:MouseEvent ):String{
var matrix:Matrix = new Matrix()
matrix.tx = 0;
matrix.ty = 0;
var finished1:BitmapData = new BitmapData(this.c1.width,this.c1.height,true,0xffffffff);
finished1.draw( this.c1, matrix );
var myImage:Image = new Image();
myImage.load( new Bitmap(finished1) );
myImage.content.width = this.c1.width;
myImage.content.height = this.c1.height;
var finished:BitmapData = new BitmapData(this.c1.width,this.c1.height,true,0xffffffff);
finished.draw(myImage);
myImage = null;
var encoder:JPEGEncoder = new JPEGEncoder();
var data:ByteArray = encoder.encode(finished);
var b64:Base64Encoder = new Base64Encoder()
b64.encodeBytes( data )
return b64.toString();
}
you probably only need to return "data" which is the JPG
Check the registration point of the source display object container.
Let's imagine the following scenario:
The display object container contains a visual like a rectangle and this DisplayObjectContainer has the registration at the bottom left so no content is available at x,y = 1,1.
BitmapData.draw would copy the content starting from 0,0(if you don't specify otherwise via a matrix translation) so you will get an empty white area(or the default fill color of the BitmapData)

Resources