I am using the HtmlTextWriter to create some HTML for me. I want to test if my page actually works but it doesnt render the div.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class web_content_notes_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
/* Configuration Start */
string thumb_directory = "img/thumbs";
string orig_directory = "img/original";
int stage_width = 600;
int stage_height = 480;
Random random = new Random();
// array of allowed file type extensions
string[] allowed_types = { "bmp", "gif", "png", "jpg", "jpeg", "doc", "xls" };
/* Opening the thumbnail directory and looping through all the thumbs: */
foreach (string file in Directory.GetFiles(thumb_directory))
{
string title = Path.GetFileNameWithoutExtension(file);
if (allowed_types.Equals(Path.GetExtension(file)) == true)
{
int left = random.Next(0, stage_width);
int top = random.Next(0, 400);
int rotation = random.Next(-40, -40);
if ((top > stage_height - 130) && (left > stage_width - 230))
{
top -= 120 + 130;
left -= 230;
}
}
//display the files in the directory in a label for testing
Label1.Text = (file);
StringWriter stringWriter = new StringWriter();
// Put HtmlTextWriter in using block because it needs to call Dispose.
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
// The important part:
writer.Write("<div>testing123</div>");
}
}
}
I want to add the various variables into the div.
How do i do this? I remember in classic asp/vbscript you had to wrap the code in <% code %> not sure if this is the case in ASP.NET / C#
I want to test if my page actually works but it doesnt render the div.
Well no, it wouldn't. Look at what you're doing:
StringWriter stringWriter = new StringWriter();
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
writer.Write("<div>testing123</div>");
So, you're writing to a StringWriter. You're then doing nothing with that string writer: the text is in memory, and you're letting it get garbage collected, basically.
If you want to write to the Page's response, you'd have to write the result to Page.Response. But you should decide whether you want control the whole of the response for the request - in which case Page probably isn't terribly appropriate - or just a single control, in which case you should probably be putting your code in a custom control.
Related
With that code I can split a multi tiff and save the images to files.
public void SplitImage(string file)
{
Bitmap bitmap = (Bitmap)Image.FromFile(file);
int count = bitmap.GetFrameCount(FrameDimension.Page);
var new_files = file.Split("_");
String new_file = new_files[new_files.Length - 1];
for (int idx = 0; idx < count; idx++)
{
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
bitmap.Save($"C:\\temp\\{idx}-{new_file}", ImageFormat.Tiff);
}
}
here the code for the Pdf creation
public void CreatePDFFromImages(string path_multi_tiff)
{
Image img = new Image(ImageDataFactory.Create(path_multi_tiff));
var p = new Paragraph("Image").Add(img);
var writer = new PdfWriter("C:\\temp\\test.pdf");
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Images"));
document.Add(p);
document.Close();
Console.WriteLine("Done !");
}
now I would like to save the images to pdf pages and tried it with iText7. But this fails as
using System.Drawing.Imaging;
using Image = iText.Layout.Element.Image;
are to close to have them both in the same class. How could I save the splitted images to PDF pages ? I would like to avoid saving first to files and reloading all the images.
The line
using Image = iText.Layout.Element.Image;
is a so-called using alias directive. It creates the alias Image for the namespace or type iText.Layout.Element.Image. If this poses a problem, you can simply create a different alias. For example
using A = iText.Layout.Element.Image;
will create the alias A for the namespace or type iText.Layout.Element.Image.
I'm stuck here while opening and reading csv file in c# program. Ive just started working upon ILNumerics to display 3D matrix graph, but the Exception rises with
"Could not find file 'C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv'."
Please help me out!
Below is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using ILNumerics;
using ILNumerics.Drawing;
using ILNumerics.Drawing.Plotting;
namespace martix
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ilPanel1_Load(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
string path = #"C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv";
StreamReader sr = new StreamReader(File.Open(path, FileMode.Open));
string dataLines = string.Empty;
while (sr.Peek() != -1)
dataLines += sr.ReadLine().Replace(";", ",") + "\n";
sr.Close();
dataLines = dataLines.Trim('\n');
//Convert the data-string into an ILArray
ILArray<int> AN = ILMath.csvread<int>(dataLines);
//Create a new scene, which is the base for our graph
var scene = new ILScene();
using (ILScope.Enter())
{
//Convert all data points to float
ILArray<float> A = ILMath.tosingle(AN);
//Add a plot to the scene and configure it
scene.Add(new ILPlotCube
{
//Render in 3D
TwoDMode = false,
//Add 3 axes
Axes =
{
XAxis =
{
Label = { Text = "Price in $" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
YAxis =
{
Label = { Text = "Rating count" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
ZAxis =
{
Label = { Text = "Download count" }
}
},
//Add the data points
Children = {
new ILPoints {
Positions = A
},
},
//Set start rotation for 3D rendered graph
Rotation = Matrix4.Rotation(new Vector3(1, 1, 1), 0.5f)
});
}
//Add the scene to the ILPanel
ilPanel1.Scene = scene;
}
}
}
It may be the spaces you have in the path. Nevermind, you're using verbatim string.
Are you sure that path is accessible and is not a networked mapped path? Can you move your file temporarily? It really seems that you don't have access to that path.
Also you should try doing the following to pinpoint the issue:
System.IO.FileInfo fi = null;
try
{
fi = new System.IO.FileInfo(path);
}
catch (ArgumentException) {... }
catch (System.IO.PathTooLongException) {... }
catch (NotSupportedException) {... }
if (ReferenceEquals(fi, null))
{
...
// file name is not valid
}
else
{
...
// file name is valid... May check for existence by calling fi.Exists.
}
EDIT:
use System.IO.Directory.GetFiles to list the exact names of the files in that folder, it may be that the file name is different (stats.csv.csv) and window explorer is hiding the extension.
Got the solution while trying. I created the csv file programatically and this time it read the file.
Just added the few line before the path and modified the path.
StringBuilder csv = new StringBuilder();
csv.AppendLine("112,113,222");
string csvpath = #"C:\\stats\xyz.csv";
File.AppendAllText(csvpath,csv.ToString());
string path = #"C:\stats\xyz.csv";
And thats it. Anyways Thanks for helping :)
I need to post several (read: a lot) PDF files to the web but many of them have hard coded file:// links and links to non-public locations. I need to read through these PDFs and update the links to the proper locations. I've started writing an app using itextsharp to read through the directories and files, find the PDFs and iterate through each page. What I need to do next is find the links and then update the incorrect ones.
string path = "c:\\html";
DirectoryInfo rootFolder = new DirectoryInfo(path);
foreach (DirectoryInfo di in rootFolder.GetDirectories())
{
// get pdf
foreach (FileInfo pdf in di.GetFiles("*.pdf"))
{
string contents = string.Empty;
Document doc = new Document();
PdfReader reader = new PdfReader(pdf.FullName);
using (MemoryStream ms = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
doc.Open();
for (int p = 1; p <= reader.NumberOfPages; p++)
{
byte[] bt = reader.GetPageContent(p);
}
}
}
}
Quite frankly, once I get the page content I'm rather lost on this when it comes to iTextSharp. I've read through the itextsharp examples on sourceforge, but really didn't find what I was looking for.
Any help would be greatly appreciated.
Thanks.
This one is a little complicated if you don't know the internals of the PDF format and iText/iTextSharp's abstraction/implementation of it. You need to understand how to use PdfDictionary objects and look things up by their PdfName key. Once you get that you can read through the official PDF spec and poke around a document pretty easily. If you do care I've included the relevant parts of the PDF spec in parenthesis where applicable.
Anyways, a link within a PDF is stored as an annotation (PDF Ref 12.5). Annotations are page-based so you need to first get each page's annotation array individually. There's a bunch of different possible types of annotations so you need to check each one's SUBTYPE and see if its set to LINK (12.5.6.5). Every link should have an ACTION dictionary associated with it (12.6.2) and you want to check the action's S key to see what type of action it is. There's a bunch of possible ones for this, link's specifically could be internal links or open file links or play sound links or something else (12.6.4.1). You are looking only for links that are of type URI (note the letter I and not the letter L). URI Actions (12.6.4.7) have a URI key that holds the actual address to navigate to. (There's also an IsMap property for image maps that I can't actually imagine anyone using.)
Whew. Still reading? Below is a full working VS 2010 C# WinForms app based on my post here targeting iTextSharp 5.1.1.0. This code does two main things: 1) Create a sample PDF with a link in it pointing to Google.com and 2) replaces that link with a link to bing.com. The code should be pretty well commented but feel free to ask any questions that you might have.
using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
//Folder that we are working in
private static readonly string WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Hyperlinked PDFs");
//Sample PDF
private static readonly string BaseFile = Path.Combine(WorkingFolder, "OldFile.pdf");
//Final file
private static readonly string OutputFile = Path.Combine(WorkingFolder, "NewFile.pdf");
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
CreateSamplePdf();
UpdatePdfLinks();
this.Close();
}
private static void CreateSamplePdf()
{
//Create our output directory if it does not exist
Directory.CreateDirectory(WorkingFolder);
//Create our sample PDF
using (iTextSharp.text.Document Doc = new iTextSharp.text.Document(PageSize.LETTER))
{
using (FileStream FS = new FileStream(BaseFile, FileMode.Create, FileAccess.Write, FileShare.Read))
{
using (PdfWriter writer = PdfWriter.GetInstance(Doc, FS))
{
Doc.Open();
//Turn our hyperlink blue
iTextSharp.text.Font BlueFont = FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.BLUE);
Doc.Add(new Paragraph(new Chunk("Go to URL", BlueFont).SetAction(new PdfAction("http://www.google.com/", false))));
Doc.Close();
}
}
}
}
private static void UpdatePdfLinks()
{
//Setup some variables to be used later
PdfReader R = default(PdfReader);
int PageCount = 0;
PdfDictionary PageDictionary = default(PdfDictionary);
PdfArray Annots = default(PdfArray);
//Open our reader
R = new PdfReader(BaseFile);
//Get the page cont
PageCount = R.NumberOfPages;
//Loop through each page
for (int i = 1; i <= PageCount; i++)
{
//Get the current page
PageDictionary = R.GetPageN(i);
//Get all of the annotations for the current page
Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);
//Make sure we have something
if ((Annots == null) || (Annots.Length == 0))
continue;
//Loop through each annotation
foreach (PdfObject A in Annots.ArrayList)
{
//Convert the itext-specific object as a generic PDF object
PdfDictionary AnnotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(A);
//Make sure this annotation has a link
if (!AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK))
continue;
//Make sure this annotation has an ACTION
if (AnnotationDictionary.Get(PdfName.A) == null)
continue;
//Get the ACTION for the current annotation
PdfDictionary AnnotationAction = (PdfDictionary)AnnotationDictionary.Get(PdfName.A);
//Test if it is a URI action
if (AnnotationAction.Get(PdfName.S).Equals(PdfName.URI))
{
//Change the URI to something else
AnnotationAction.Put(PdfName.URI, new PdfString("http://www.bing.com/"));
}
}
}
//Next we create a new document add import each page from the reader above
using (FileStream FS = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document Doc = new Document())
{
using (PdfCopy writer = new PdfCopy(Doc, FS))
{
Doc.Open();
for (int i = 1; i <= R.NumberOfPages; i++)
{
writer.AddPage(writer.GetImportedPage(R, i));
}
Doc.Close();
}
}
}
}
}
}
EDIT
I should note, this only changes the actual link. Any text within the document won't get updated. Annotations are drawn on top of text but aren't really tied to the text underneath in anyway. That's another topic completely.
Noted if the Action is indirect it will not return a dictionary and you will have an error:
PdfDictionary AnnotationAction = (PdfDictionary)AnnotationDictionary.Get(PdfName.A);
In cases of possible indirect dictionaries:
PdfDictionary Action = null;
//Get action directly or by indirect reference
PdfObject obj = Annotation.Get(PdfName.A);
if (obj.IsIndirect) {
Action = PdfReader.GetPdfObject(obj);
} else {
Action = (PdfDictionary)obj;
}
In that case you have to investigate the returned dictionary to figure out where the URI is found. As with an indirect /Launch dictionary the URI is located in the /F item being of type PRIndirectReference with the /Type being a /FileSpec and the URI located in the value of /F
Added code for dealing with indirect and launch actions and null annotation-dictionary:
PdfReader r = new PdfReader(#"d:\kb2\" + f);
for (int i = 1; i <= r.NumberOfPages; i++) {
//Get the current page
var PageDictionary = r.GetPageN(i);
//Get all of the annotations for the current page
var Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);
//Make sure we have something
if ((Annots == null) || (Annots.Length == 0))
continue;
foreach (var A in Annots.ArrayList) {
var AnnotationDictionary = PdfReader.GetPdfObject(A) as PdfDictionary;
if (AnnotationDictionary == null)
continue;
//Make sure this annotation has a link
if (!AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK))
continue;
//Make sure this annotation has an ACTION
if (AnnotationDictionary.Get(PdfName.A) == null)
continue;
var annotActionObject = AnnotationDictionary.Get(PdfName.A);
var AnnotationAction = (PdfDictionary)(annotActionObject.IsIndirect() ? PdfReader.GetPdfObject(annotActionObject) : annotActionObject);
var type = AnnotationAction.Get(PdfName.S);
//Test if it is a URI action
if (type.Equals(PdfName.URI)) {
//Change the URI to something else
string relativeRef = AnnotationAction.GetAsString(PdfName.URI).ToString();
AnnotationAction.Put(PdfName.URI, new PdfString(url));
} else if (type.Equals(PdfName.LAUNCH)) {
//Change the URI to something else
var filespec = AnnotationAction.GetAsDict(PdfName.F);
string url = filespec.GetAsString(PdfName.F).ToString();
AnnotationAction.Put(PdfName.F, new PdfString(url));
}
}
}
//Next we create a new document add import each page from the reader above
using (var output = File.OpenWrite(outputFile.FullName)) {
using (Document Doc = new Document()) {
using (PdfCopy writer = new PdfCopy(Doc, output)) {
Doc.Open();
for (int i = 1; i <= r.NumberOfPages; i++) {
writer.AddPage(writer.GetImportedPage(r, i));
}
Doc.Close();
}
}
}
r.Close();
I am using iTextSharp to create a .pdf. I've got a table and in the table, I need to populate two checkboxes based on data.
My code looks like this. dv is the dataview containing the data, and chkchecked and chkunchecked are gifs of a checked box and unchecked box respectively.
Pdfpcell cell = new Pdfpcell(new Phrase(""));
cell.AddElement ((int)dv[i]["Return_Reason"] == 6 ? chkchecked : chkunchecked);
Phrase p = new Phrase ("item was not authorized for the payee")
cell.AddElement (p);
cell.AddElement ((int)dv[i]["Return_Reason"] == 7 ? chkchecked : chkunchecked);
p = new Phrase ("item was not authorized for the amount")
cell.AddElement (p);
table.AddCell (cell);
And this almost works. But my checkboxes are on the line above the respective text, and I want the check boxe to line up beside the text that follows it. How do I get the gif to share the line with the following text in the cell?
The trick is to wrap the individual images in a Chunk and then wrap that and the text inside of a Paragraph. When you create a Chunk from an iTextSharp.text.Image you need to specify at least two floats representing x and y offsets. The sample below uses 0 for both but if you see your image riding too high try using a negative, like -3 for the y parameter. Also, my sample images were a little too big so I needed to scale them down.
Below is a full working WinForms example targeting iTextSharp 5.1.1.0. See the code for additional comments.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace Full_Profile1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string workingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string outputFile = Path.Combine(workingFolder, "Test.pdf");
string checkedImagePath = Path.Combine(workingFolder, "checked.png");
string uncheckedImagePath = Path.Combine(workingFolder, "unchecked.png");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
{
//Open our document for writing
doc.Open();
//Create images from our file paths
var chkchecked = iTextSharp.text.Image.GetInstance(checkedImagePath);
var chkunchecked = iTextSharp.text.Image.GetInstance(uncheckedImagePath);
//Scale the images to an appropriate size (if needed)
chkchecked.ScaleAbsolute(12, 12);
chkunchecked.ScaleAbsolute(12, 12);
//Create a Paragraph object to contain our images and text
Paragraph p = new Paragraph();
//Add an image
p.Add(new Chunk(chkchecked, 0, 0));
//Add some text
p.Add("checked");
//Add another image
p.Add(new Chunk(chkunchecked, 0, 0));
//Add some more text
p.Add("checked");
//Create a one column table
PdfPTable table = new PdfPTable(1);
//Create a cell for the table
PdfPCell cell = new PdfPCell();
//Add the paragraph to the cell
cell.AddElement(p);
//Add the cell to the table
table.AddCell(cell);
//Add the table to the document
doc.Add(table);
//Close the document
doc.Close();
}
}
}
this.Close();
}
}
}
I am using the .NET WebBrowser control to as a WYSIWYG html editor. I've been using the ExecCommand to do the formatting function fine so far, however I now want to add a table inserter. The problem is I can only seem to Append the table to the document, not insert it half way through. Below is some basic test code, if anyone can help, I'd appreciate it.
HtmlElement tableRow = null;
HtmlElement headerElem = null;
HtmlDocument doc = wbDesign.Document;
HtmlElement tableElem = doc.CreateElement("TABLE");
doc.Body.AppendChild(tableElem);
HtmlElement tableHeader = doc.CreateElement("THEAD");
tableElem.AppendChild(tableHeader);
tableRow = doc.CreateElement("TR");
tableHeader.AppendChild(tableRow);
headerElem = doc.CreateElement("TH");
headerElem.InnerText = "Col1";
tableRow.AppendChild(headerElem);
headerElem = doc.CreateElement("TH");
headerElem.InnerText = "Col2";
tableRow.AppendChild(headerElem);
HtmlElement tableBody = doc.CreateElement("TBODY");
tableElem.AppendChild(tableBody);
tableRow = doc.CreateElement("TR");
tableBody.AppendChild(tableRow);
HtmlElement tableCell = doc.CreateElement("TD");
tableCell.InnerText = "Test";
tableRow.AppendChild(tableCell);
tableCell = doc.CreateElement("TD");
tableCell.InnerText = "Test";
tableRow.AppendChild(tableCell);
You need to navigate the HtmlDocument structure, finding the node at where you want to insert it, and then append there. If you Append to the Body, you'll just add to the end of the last element, i.e. the end.
Its a bit late - but I recently had this requirment and came up with this. I've tried to make this a minimal as possible, to show the methodology, and allow you to customise this a required.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.HtmlControls;
using System.Windows.Forms;
using System.IO;
using System.Web.UI;
public class HtmlToWebBrowserControlDoc
{
// The loaded document MUST have a script similar to this
// <script type="text/javascript" >
// function appendHtml(o) {
// var div = document.createElement("div");
// div.innerHTML = o;
// document.body.appendChild( div);
// }
// </script>
public static void InsertHtmlControl(HtmlControl c, WebBrowser wb)
{
// create a HtmlTextWriter;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htmlw = new HtmlTextWriter(sw);
// render the control as html
c.RenderControl(htmlw);
//invoke the script passing in the html
object[] p = new object[1];
p[0] = (object)sb.ToString();
wb.Document.InvokeScript("appendHtml", p);
htmlw.Close();
htmlw.Dispose();
sw.Dispose();
}
}
[DllImport("user32.dll")]
public static extern bool GetCaretPos(ref Point pt);
.....
HtmlElement newElement = webBrowser.Document.CreateElement("<div></div>");
Point p = new Point();
GetCaretPos(ref p);
HtmlElement currentElement = webBrowser.Document.GetElementFromPoint(p);
currentElement.InsertAdjacentElement(HtmlElementInsertionOrientation.AfterBegin, newElement);