Solved

.ASP.NET Batch PDF create using provided list of ID's

Posted on 2014-10-07
18
148 Views
Last Modified: 2014-12-01
Hi all,

Need some help modifying an .aspx function to loop through a list and generate PDF files.  The list will be generated later, but assume it is a basic comma-delimited list of id's like "100278", "100279", 100280", etc.

The .aspx file, as it exists now.  I'm pasting the whole thing to show existing references.

I need to create a new function similar to the btnPDF_Click() function, but it needs to loop through a list of Manifest numbers to create individual PDF's to a local directory (instead of using the single Manifest declared in the Page_Load() function).  

Business case: a user needs to re-download and re-print 900 of these things - doing it one-by-one would be painful.  

Any help would be much appreciated!

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ExtenData.MobilityCommon.Common.Util;
using Able.Data;
using Able.Web;
using System.IO;

public partial class Manifests_View : System.Web.UI.Page
{
    private Manifest manifest = null;
    private ManifestDetailCollection detailList = new ManifestDetailCollection();
    private string redirect = "Default";

    protected void Page_Load(object sender, EventArgs e)
    {
        manifest = Manifest.FetchByID(ServiceHelper.getInt(Request["ManifestId"]));
        if (manifest == null)
        {
            Response.Redirect("Default.aspx");
            return;
        }
        else
        {
            Top1.Title = "View Manifest";
            Able.Web.HistoryManager.AddPage(Request.Url.PathAndQuery, "View Manifest: " + manifest.ManifestNumber);
        }

        if (new ConfigManager().GetBool("Allow Fax"))
            pnlFax.Visible = true;

        if (ServiceHelper.ifNull(Request["redirect"]).Length > 0)
            redirect = Request["redirect"];

        lblPageTitle.Text = Top1.Title;

        if (Roles.IsUserInRole("XTend Administrator") || Roles.IsUserInRole("Administrator"))
            btnAudit.Visible = true;

        if (manifest.ManifestStatus == ManifestStatus.Disposed)
            btnEdit.Visible = false;
    }

    protected void btnPdf_Click(object sender, EventArgs e)
    {
        Response.Clear();
        Response.Charset = "";

        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", "attachment; filename=\"" + manifest.ManifestNumber + ".pdf\"");

        Dictionary<string, object> parms = new Dictionary<string, object>();
        parms.Add("Include Header", true);
        byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), parms);

        Response.OutputStream.Write(bytes, 0, bytes.Length);

        Response.Flush();
        Response.End();
    }

    protected void btnSendPdf_Click(object sender, EventArgs e)
    {
        Dictionary<string, object> parms = new Dictionary<string, object>();
        parms.Add("Include Header", true);
        byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), parms);

        string email = txtEmails.Text.Replace(';', ',');

        List<string> emails = new List<string>();
        string[] split = email.Split(',');
        foreach (string s in split)
            emails.Add(s.Trim());

        AbleUser user = AbleUser.FetchUserByUsername(Page.User.Identity.Name);

        string[] bcc = null;
        if (chkBcc.Checked)
            bcc = new string[] { user.Email };

        Dictionary<string, byte[]> fileBytes = new Dictionary<string, byte[]>();
        fileBytes.Add(manifest.ManifestNumber + ".pdf", bytes);

        EmailHelper.SendEmail(elm1.Value,
            new ConfigManager().GetString("Email From", null),
            emails.ToArray(),
            null,
            bcc,
            "Manifest",
            null,
            fileBytes);
    }

    protected void btnSendFax_Click(object sender, EventArgs e)
    {
        Dictionary<string, object> parms = new Dictionary<string, object>();
        parms.Add("Include Header", true);
        byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), parms);

        string fax = ServiceHelper.ifNull(txtFax.Text).Replace(" ", "").Replace("-", "").Replace(".", "").Replace("(", "").Replace(")", "");
        string email = fax + new ConfigManager().GetString("Fax To", null);

        string from = new ConfigManager().GetString("Fax From", null);

        AbleUser user = AbleUser.FetchUserByUsername(Page.User.Identity.Name);

        Dictionary<string, byte[]> fileBytes = new Dictionary<string, byte[]>();
        fileBytes.Add(manifest.ManifestNumber + ".pdf", bytes);

        EmailHelper.SendEmail(elm1.Value,
            from,
            new string[] { email },
            null,
            null,
            "Manifest",
            null,
            fileBytes);
    }

    protected void btnEdit_Click(object sender, EventArgs e)
    {
        Response.Redirect("Detail.aspx?ManifestId=" + manifest.ManifestId + "&redirect=" + redirect);
    }

    protected void backButton_Click(object sender, EventArgs e)
    {
        Response.Redirect(redirect + ".aspx");
    }

    protected void btnCancel_Click(object sender, EventArgs e)
    {
        ObjectsRemoved r = new ObjectsRemoved();
        r.RemovedByUser = User.Identity.Name;
        r.RemovedTime = DateTime.Now;
        r.Category = "Manifest";
        r.Extra1 = manifest.ManifestNumber;
        r.Save();

        ChangeManager.TrackRemoved("Manifest Removed", manifest.ManifestId, manifest.ManifestNumber, manifest, User.Identity.Name, new System.Collections.Generic.List<string>());
        ManifestDetailCollection detail = manifest.Detail;
        foreach (ManifestDetail d in detail)
            ChangeManager.TrackRemoved("Manifest Detail Removed", d.DetailId, manifest.ManifestNumber, d, User.Identity.Name, new System.Collections.Generic.List<string>());

        ServiceHelper.UpdateSql("delete from able_ManifestNote where ManifestId=" + manifest.ManifestId);
        ServiceHelper.UpdateSql("delete from able_ManifestDetail where ManifestId=" + manifest.ManifestId);
        ServiceHelper.UpdateSql("delete from able_Manifest where ManifestId=" + manifest.ManifestId);
        //manifest.ManifestStatus = ManifestStatus.Cancel;
        //manifest.Save(User.Identity.Name);
        //Response.Redirect("View.aspx?ManifestId=" + manifest.ManifestId);

        List<PageHistory> history = (List<PageHistory>)Session["PAGE_HISTORY"];
        if (history != null && history.Count > 1)
        {
            int index = history.Count - 2;
            if (index > -1)
            {
                PageHistory page = history[index];
                Response.Redirect(page.Url);
                return;
            }
        }

        Response.Redirect(redirect + ".aspx");
    }

    protected void btnAudit_Click(object sender, EventArgs e)
    {
        Response.Redirect("~/Reports/Audit.aspx?s=" + manifest.ManifestNumber);
    }
}

Open in new window

0
Comment
Question by:Lakin IT
  • 7
  • 6
  • 2
  • +1
18 Comments
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
why not copy (or move) your code from btnPdf_Click and put it in it's own function, with a parameter for the ID. then wherever the IDs are coming from, put them in some kind of collection, such as an array, or list, or whatevers appropriate, loop through that collection, can call your newly created function with the ID as the parameter
0
 

Author Comment

by:Lakin IT
Comment Utility
@BigMonty - that's exactly what I want to do, but need help with the syntax.
0
 

Author Comment

by:Lakin IT
Comment Utility
This is the direction I'm heading - close?

    protected void createBatchPDFs(object sender, EventArgs e)
    {

        List string list_of_manifests = "1234, 1235, 1236";

        foreach (var manifestid in list_of_manifests)
        {

            Response.Clear();
            Response.Charset = "";

            Response.ContentType = "application/pdf";
            Response.AddHeader("Content-Disposition", "attachment; filename=\"" + manifest.ManifestNumber + ".pdf\"");

            Dictionary<string, object> parms = new Dictionary<string, object>();
            parms.Add("Include Header", true);
            byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), manifestid);

            Response.OutputStream.Write(bytes, 0, bytes.Length);

            Response.Flush();
            Response.End();

        }

    }

Open in new window

0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
I'm a classic asp guy (where this was originally posted), with experience in vb.net.  c# is def not my strong suit, you may want to his "Request Attention" to get one of the mods to send an additional message to .NET experts
0
 

Author Comment

by:Lakin IT
Comment Utility
Ok - I'll see if the mods can send to .NET.
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
Comment Utility
BM, you can obviously see this is not Classic ASP.  You answered as if you knew what you are talking about.  If you don't know the topic, then don't participate in it from the start and mislead people.
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
Scott - I didn't mislead anyone. No one had answered the question in roughly 8 hours, so I took a stab at it, explaining the steps I would take. There was no mention of syntax in the original post, so I mis-understood it to be needing the logical steps to be thought out. Just because I mis-understood something doesn't mean i "misled" someone. Next time you want to attack my character, do so via private message. In the meantime, I've sent a message to an actual mod to come in and clean up your comments.

Lakin - I apologize for getting off topic above... From the very little of c# I do know, it looks like you're on the right track, however I think you'll want to move your Response.End to AFTER your foreach loop, otherwise you'll only process just one pdf doc.
0
 

Author Comment

by:Lakin IT
Comment Utility
Thank you for your help, @BM.  FWIW, I didn't feel misled at all and appreciate the assistance - especially since yours has  been the only response to date.  I'm a CF dev and not entirely clear on .NET vs. .ASP, but was thinking mod's response was a little harsh to an attempt to help as well.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
Thx Lakin - much appreciated...

the difference between the 2 technologies is that classic asp is much more similar to php, since it is more of a scripting language, and .NET is more object oriented.

any luck with your code? are you getting any errors or is it just not working?
0
 

Author Comment

by:Lakin IT
Comment Utility
I'm getting this error:  

CS1502: The best overloaded method match for 'Able.Data.ManifestPdf.Generate(Able.Data.Manifest, string, System.Collections.Generic.Dictionary<string,object>)' has some invalid arguments

Open in new window


On this line:

byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), manifestid);

Open in new window


And this is what my function looks like now:

protected void createBatchPDFs(object sender, EventArgs e)
    {

        List<string> list_of_manifests = new List<string>();
        list_of_manifests.Add("12345");
        list_of_manifests.Add("67890");
        list_of_manifests.Add("13579");
        list_of_manifests.Add("24680");

        foreach (var manifestid in list_of_manifests)
        {

            Response.Clear();
            Response.Charset = "";

            Response.ContentType = "application/pdf";
            Response.AddHeader("Content-Disposition", "attachment; filename=\"" + manifest.ManifestNumber + ".pdf\"");

            Dictionary<string, object> parms = new Dictionary<string, object>();
            parms.Add("Include Header", true);
            byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), manifestid);

            var uploadPath = Server.MapPath("~/_TEMP/PDF");
            var tempfilename = Guid.NewGuid().ToString();
            var tempfilenameandlocation = Path.Combine(uploadPath, Path.GetFileName(tempfilename));

            File.WriteAllBytes( tempfilenameandlocation, bytes);

            Response.Flush();

        }

            Response.End();

    }

Open in new window

0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
what is the data type for the variable manifestid? assuming you want it to be an INT, try changing your foreach statement to"

foreach (int manifestid in list_of_manifests)

Open in new window

0
 

Author Comment

by:Lakin IT
Comment Utility
No luck there, but thank you for your help.  

I ended up reconstructing the function outside of the system in Coldfusion - so far so good.
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
excellent, glad you got it working :)
0
 
LVL 52

Accepted Solution

by:
_agx_ earned 500 total points
Comment Utility
(no points...just an observation about the code)

>> Source comment
>> This is the direction I'm heading - close?

Without testing it, looks like that code attempts to return multiple files to a single http request. ie

              -- download 1234.pdf
              -- download 1235.pdf
              -- download 1236.pdf

You can't really do that with http. It's designed to return a single file per http request.

If you want to allow a user to download say 20 files, you either need to a) zip the 20 files into a single archive and download the .zip file -OR- possibly merge them into one big pdf (like with cfpdf action="merge". and download that file
0
 

Author Comment

by:Lakin IT
Comment Utility
I don't want to return multiple files per request - I know that's what the code looks like - I just didn't get rid of all of the Response stuff.

I simply wanted to loop a given list of manifest ID's and create a PDF for each one.  They didn't need to go to a browser session, just a local directory on disk.
0
 
LVL 52

Expert Comment

by:_agx_
Comment Utility
Gotcha.

I can't test any of this right now, but I'd go with the approach suggested earlier.  Create a method that generates a single pdf and saves it to a temp file:

protected string SavePDFToTempFile(int manifestID) {
    // lookup manifest by id first
    Manifest manifest = Manifest.FetchByID(manifestID);
    Dictionary<string, object> parms = new Dictionary<string, object>();
    parms.Add("Include Header", true);
    byte[] bytes = ManifestPdf.Generate(manifest, File.ReadAllText(Server.MapPath("~/Manifests/" + ManifestPdf.GetXmlFileName(manifest))), parms);

    // save bytes to temp file
    string uploadPath = Server.MapPath("~/_TEMP/PDF");
    string tempfilename = Guid.NewGuid().ToString();
    string tempfilenameandlocation = Path.Combine(uploadPath, Path.GetFileName(tempfilename));
    File.WriteAllBytes( tempfilenameandlocation, bytes);

    // return file path
    return tempfilenameandlocation ;
}

Open in new window


Then call that method within your loop. Note, it didn't seem like the id's were strings, so I changed the List type "int".

    List<int> list_of_manifests = new List<int>();
    list_of_manifests.Add(12345);
    list_of_manifests.Add(67890);
    list_of_manifests.Add(13579);
    list_of_manifests.Add(24680);

    foreach (int manifestid in list_of_manifests) 
    {
       string savedToFile = SavePDFToTempFile(manifestid);
       // maybe save the file names to an array here ...
      
    }

Open in new window

0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now