i am working on MVC application i have to export my table data and i am using following code :
public ActionResult ExportData()
{
GridView gv = new GridView();
gv.DataSource = db.Studentrecord.ToList();
gv.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=Marklist.xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gv.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return RedirectToAction("StudentDetails");
}
this creates single worksheet i want another worksheet where i will have other table data.Please help how to export data in multiple worksheet ?
How about using a 3rd party library instead? This is free: https://code.google.com/p/excellibrary/
string file = "C:\\newdoc.xls";
Workbook workbook = new Workbook();
Worksheet worksheet = new Worksheet("First Sheet");
Worksheet worksheet2 = new Worksheet("Second Sheet");
workbook.Worksheets.Add(worksheet);
workbook.Worksheets.Add(worksheet2);
workbook.Save(file);
This provides a much more fluid user experience as you are actually creating a real Excel file, not just a HTML file which Excel happens to read.
Related
I have the following code:
public byte[] ExportToPdf(DataTable dt)
{
iTextSharp.text.Document document = new iTextSharp.text.Document();
document.Open();
iTextSharp.text.Font font5 = iTextSharp.text.FontFactory.GetFont(FontFactory.HELVETICA, 5);
PdfPTable table = new PdfPTable(dt.Columns.Count);
PdfPRow row = null;
float[] widths = new float[] { 4f, 4f, 4f, 4f, 4f, 4f, 4f, 4f };
table.SetWidths(widths);
table.WidthPercentage = 100;
foreach (DataColumn c in dt.Columns)
{
table.AddCell(new Phrase(c.ColumnName, font5));
}
document.Add(table);
document.Close();
byte[] bytes;
MemoryStream msPDFData = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, msPDFData);
return msPDFData.ToArray();
}
And in another function i call the function like this:
byte[] bytes = ExportToPdf(table);
return File(bytes, "application/pdf", "RaportDocumenteEmise.pdf");
When i try to open the pdf it says that is damaged.
Somehow the byte array is empty.
Can say me what am i doing wrong?
This is wrong:
iTextSharp.text.Document document = new iTextSharp.text.Document();
document.Open();
A PDF is created using 5 simple steps:
Create a Document object
Create a PdfWriter instance
Open the document
Add content
Close the document
You don't have step 2. In your comment, you say that you've solved the problem by creating that instance after opening the document, but that's wrong! You need to create the PdfWriter instance before opening the document.
Opening the document writes the PDF header to the OutputStream. That can't happen without a valid PdfWriter instance.
I was trying to do the same thing as you.
After many tries, I discovered that if I put PdfWriter.GetInstance
inside using (var ms = new MemoryStream()) { } everything works alright!
My full code is:
public FileContentResult GetPDF() {
string htmlContent = "<p>First line</p><p>Second line</p>";
StringReader sr = new StringReader(htmlContent);
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f);
HTMLWorker hw= new HTMLWorker(pdfDoc);
FileContentResult result;
using (var ms = new MemoryStream()) {
PdfWriter.GetInstance(pdfDoc, ms);
pdfDoc.Open();
hw.Parse(sr);
pdfDoc.Close();
result = this.File(ms.ToArray(), "application/pdf", "teste.pdf");
}
return result;
}
Ps.: This is a method inside my Controller.
I created a pdf form in LiveCycle, saved and reader enabled. I have 2 buttons on the form. The first button hits a webservice to populate a dropdown list n the form, and the other button is a submit, which submits the XML data to an MVC Controller method and puts the xml data in a sql database. There is another MVC Controller method the uses itextsharp to open the LiveCycle pdf and fill it with the xml data from SQL. My problem is that the form, after it uses the itextSharp stuff to do its thing, need to be able to resubmit any changes to the form using the submit button. 2 things are happening, and I am not Flattening the form. 1) The button that hits the webservice to populate the dropdownlist does not show unless I scroll out of view and back in. But even then, the dropdownlist shows what was chosen, but cannot be repopulated. Like the button doesn't work or something. 2) The submit button will not work either. I can click, but it does nothing. Any help is appreciated. My code that uses itextsharp is below.
public void PDFBuilder(int FormID)
{
int id = 0;
id = FormID;// Convert.ToInt32(Request.QueryString["ID"]);
var oRow = db.SubmissionsGenerals.Find(id);
string fv = db.FormVersions.Where(w => w.GUID == oRow.FormGUID).Select(s => s.FormPathFillable).First();
string xML = string.Empty;
xML = oRow.XMLData.ToString();
XmlDocument oXmlData = new XmlDocument();
oXmlData.LoadXml(xML);
string m_FormsPath = "http://myformsurl" + fv.TrimStart('.');
fv = fv.TrimStart('.');
if (fv != null)
{
MemoryStream ms = GeneratePDF(m_FormsPath, oXmlData);
byte[] bytes = ms.ToArray();
Response.ContentType = "application/pdf";
Response.BinaryWrite(bytes);
Response.End();
}
}
public MemoryStream GeneratePDF(string m_FormName, XmlDocument oData)
{
PdfReader pdfTemplate;
PdfStamper stamper;
PdfReader tempPDF;
Document doc;
MemoryStream msTemp;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();
pdfTemplate = new PdfReader(m_FormName);
doc = new Document();
pCopy = new PdfCopy(doc, msOutput);
pCopy.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, new PdfBoolean(true));
pCopy.AddViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
doc.Open();
for(int i=1; i<pdfTemplate.NumberOfPages + 1; i++)
{
msTemp = new MemoryStream();
pdfTemplate = new PdfReader(m_FormName);
stamper = new PdfStamper(pdfTemplate, msTemp);
foreach(XmlElement oElem in oData.SelectNodes("/form1/*"))
{
stamper.AcroFields.SetField(oElem.Name, oElem.InnerText);
}
//stamper.FormFlattening = true;
stamper.Close();
tempPDF = new PdfReader(msTemp.ToArray());
((PdfCopy)pCopy).AddPage(pCopy.GetImportedPage(tempPDF, i));
pCopy.FreeReader(tempPDF);
}
doc.Close();
return msOutput;
}
I have basic code that creates the file in a console (See below).. But I am writing a MVC app so I need to return that XML document as an ActionResult.... Ive been searching the web 2 hours looking for a simple example with no luck..
What do I add to this to make it a ActionResult ?
string filePath = #"C:\temp\OpenXMLTest.docx";
using (WordprocessingDocument doc = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))
{
//// Creates the MainDocumentPart and add it to the document (doc)
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello World!!!!!")))));
}
Here's some sample code. Note this code doesn't load the file from disk, it creates the file on-the-fly and writes to a MemoryStream. The changes needed to write to disk are minimal.
public ActionResult DownloadDocx()
{
MemoryStream ms;
using (ms = new MemoryStream())
{
using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(ms, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello world!")))));
}
}
return File(ms.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "Test.docx");
}
this is my controller class:-
public class PlantHeadController : Controller
{
private WOMSEntities2 db = new WOMSEntities2();
//
// GET: /PlantHead/
Document doc = new Document();
static String[] tt=new String[20];
public ActionResult Index()
{
ViewBag.productCode = new SelectList(db.Product, "ID","code");
return View();
}
public void Convert()
{
PdfWriter.GetInstance(doc, new
FileStream((Request.PhysicalApplicationPath + "\\Receipt3.pdf"),
FileMode.Create));
doc.Open();
PdfPTable table = new PdfPTable(2);
doc.AddCreationDate();
PdfPCell cell = new PdfPCell(new Phrase("Receipt"));
cell.Colspan = 3;
cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.AddCell(cell);
table.AddCell("ahym");
table.AddCell("ram";
table.AddCell("good");
table.AddCell("morning");
String rawGroup = "";
foreach (String lll in raw)
rawGroup = rawGroup + lll+" ";
table.AddCell("" + rawGroup);
doc.Add(table);
doc.Close();
Response.Redirect("~/Receipt3.pdf");
}
}
whenever i press submit button to make pdf file then this error window is opened:-
means pdf is not generated successfully. in some cases old pdf is shown. please suggest me what should i do?
Everything looks good for the most part above (except a missing parenthesis on table.AddCell("ram"; which I assume is just a typo and you could also do with some using statements). I don't know why you would get an error but the reason that you're getting the same PDF is almost definitely because of browser caching. You could append a random querystring to the file but I'd recommend instead skipping the file completely and writing the binary stream directly. This way you can control the caching and you don't have to work about browser redirection. The below code should work for you (its targeting 5.1.1.0 depending on your version you may or may not be able to use some of the using statements).
EDIT
I donwgraded my code to not use the IDisposable interfaces found in newer versions, this should work for you now. (I don't have access to a C# compiler so I didn't test it so hopefully this works.)
using (MemoryStream ms = new MemoryStream())
{
Document doc = new Document());
PdfWriter writer = PdfWriter.GetInstance(doc, ms));
doc.Open();
doc.AddCreationDate();
PdfPTable table = new PdfPTable(2);
PdfPCell cell = new PdfPCell(new Phrase("Receipt"));
cell.Colspan = 3;
cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.AddCell(cell);
table.AddCell("ahym");
table.AddCell("ram");
table.AddCell("good");
table.AddCell("morning");
String rawGroup = "";
foreach (String lll in raw)
{
rawGroup = rawGroup + lll + " ";
}
table.AddCell("" + rawGroup);
doc.Add(table);
doc.Close();
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Receipt3.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(ms.ToArray());
System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest();
}
I have been trying to generate simple PDFs from my app so that I can later move on to generating PDF with dynamic data. My code generates the files but I want a way to also have the browser prompt the download of the file.
I actually don't even want to store generated files on my server but I'm not sure how to get it to just provide it to the user without first storing it in the server drive.
public ActionResult GetPDF()
{
Document document = new Document();
PdfWriter.GetInstance(document, new FileStream(Server.MapPath("../Content/test.pdf"), FileMode.Create));
document.Open();
string strHTML = "<B>I Love ASP.Net!</B>";
HTMLWorker htmlWorker = new HTMLWorker(document);
htmlWorker.Parse(new StringReader(strHTML));
document.Close();
return File(document, "application/pdf", Server.HtmlEncode(filename));//this doesnt work, obviously
}
Use a FileStreamResult Action
public FileStreamResult Export(int? ID)
{
MemoryStream stream = new MemoryStream();
//Start of PDF work using iTextSharp PDF library
Document pdf = new Document();
PdfWriter writer = PdfWriter.GetInstance(pdf, stream);
pdf.Open();
pdf.Add(new Phrase("test"));
pdf.Close();
//End of PDF work using iTextSharp PDF library
//Where the download magic happens
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Log.pdf");
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
return new FileStreamResult(Response.OutputStream, "application/pdf");
}
you need to do something like...
change
PdfWriter.GetInstance(document, new FileStream(Server.MapPath("../Content/test.pdf"), FileMode.Create));
to
var memorystream ms = new memorystream;
PdfWriter.GetInstance(document, ms);
and then at the end...
Response.Clear;
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=PDFFile.pdf");
ms.Write(Response.OutputStream);