2

I have written some visualforce pages in which there are various PageMessages I have added for validations.

If validations fails, error is showing on the top of pageblock.

I want to log those errors in a csv file, and want to give the user a downlodable link for the created csv file.

how to do this in apex or visualforce?

Visualforce Page:

<apex:page controller="MergeAccountSearchController" contentType="text/csv#testCSV.csv" >
    Rec Id,Rec Name,Error Message 
    <apex:repeat value="{!failRecId}" var="recId"> {!recId}</apex:repeat> 
    <apex:repeat value="{!failRecName}" var="recName"> 
        {!recName}
    </apex:repeat> 
    <apex:repeat value="{!errors}" var="error"> 
        {!error}
    </apex:repeat>
</apex:page>

But it's not giving output as expected.

Expected Output:

enter image description here

Expected Output:

enter image description here

5
  • 1
    There are plenty of questions posted across the board regarding this. Please post some code you have used and are having difficulty with the end result. Take a look into this and review the logic used to get a head start on your functionality.
    – TSmith
    Mar 8, 2017 at 12:04
  • -1 from me for lack of research. Also, if you don't provide some code that you've worked on, then your question comes off as a "do it for me" request, which generally don't fare so well.
    – Derek F
    Mar 8, 2017 at 13:46
  • <apex:page controller="MergeAccountSearchController" contentType="text/csv#testCSV.csv" >Rec Id,Rec Name,Error Message <apex:repeat value="{!failRecId}" var="recId"> {!recId}</apex:repeat> <apex:repeat value="{!failRecName}" var="recName"> {!recName}</apex:repeat> <apex:repeat value="{!errors}" var="error"> {!error}</apex:repeat></apex:page> Mar 8, 2017 at 13:51
  • was not able to add code in question so I put in comments. @DerekF Mar 8, 2017 at 13:52
  • 1
    @AnkurGupta You can add that to your question, you'll just need to format it properly for Stackexchange not to mangle it (using either back-ticks, which is just to the left of the '1' key on an English qwerty keyboard, or by formatting it as a code block by highlighting your code, and then pressing ctrl + k). I'll edit your question to include your Visualforce page this time, and I'll also retract my downvote.
    – Derek F
    Mar 8, 2017 at 14:16

1 Answer 1

1

It's hard to say exactly what you'll need to do without seeing the code for your controller as well, but I can still make some targeted suggestions.

First, just for sake of completeness, a csv file is simply a text file that uses commas to separate columns, and newlines (\n or \r\n) to separate rows.

The reason why you're getting each cell of data on a new row in your output is because <apex:repeat> inserts a newline after it finishes each iteration.

If you take a look at the raw output of your Visualforce page (by pressing ctrl + u in most modern browsers), you'll see it looks something like this:

Rec Id,Rec Name,Error Message
<id of the first record>
<id of the second record>
Allen Solly
Joe Trib
Mailing and Shipping Postal Code must be the same if contact is related to account
Mailing and Shipping Postal Code must be the same if contact is related to account

The raw output that you're looking for would be something like this

Rec Id,Rec Name,Error Message
<id of the first record>,Allen Solly,Mailing and Shipping Postal Code must be the same if contact is related to account
<id of the second record>,Joe Trib,Mailing and Shipping Postal Code must be the same if contact is related to account

Keeping in mind that <apex:repeat> adds newlines after each iteration, the desired raw output should tell you that you only want to have a single <apex:repeat> in your Visualforce page.

This should also give you a hint as to how you'll need to structure your data in your controller.

I imagine that your controller currently looks something like this

public class MergeAccountSearchController{
    List<String> failRecId {get;set;}
    List<String> failRecName {get; set;}
    List<String> errors {get;set;}

    // Other code that I have no idea about
}

It's likely possible that you could access the correct value from all 3 lists in a single <apex:repeat>, but that would be doing things the hard way. Instead, it makes more sense to somehow consolidate the information from these 3 lists into a single list. We can do this with an inner class.

public class MergeAccountSearchController{
    // We want to end up with a single list, which will make iterating through
    //   it using <apex:repeat> easy.
    // 'ErrorWrapper' is the name of the inner class that we'll be defining later.
    List<ErrorWrapper> errors {get;set;}

    // Start of code that I have no idea about
      <some code here>
    // End of code that I have no idea about

    // Each instance of ErrorWrapper will contain all of the data we want to show
    //   in a single row of the resulting csv file
    public class ErrorWrapper{
        String failRecId {get;set;}
        String failRecName {get;set;}
        String error {get;set;}

        // basic constructor, not much to talk about
        public ErrorWrapper(String recId, String recName, String error){
            failRecId = recId;
            failRecName = recName;

            // This is the only interesting line in the constructor.
            // The 'error' parameter has exactly the same name as the 'error'
            //   class attribute.
            // This is called shadowing. The parameter name shadows the attribute name.
            // To access the attribute, we'll need to use 'this'
            this.error = error;
        }
}

With that in place, we can make the changes to your visualforce page that will get you the output you're looking for.

<!-- Don't forget about putting the commas in between each piece of data -->
<apex:page controller="MergeAccountSearchController" contentType="text/csv#testCSV.csv" >
    Rec Id,Rec Name,Error Message 
    <apex:repeat value="{!errors}" var="err">
        {!err.failRecId},{!err.failRecName},{!err.error}
    </apex:repeat> 
</apex:page>

Populating the List<ErrorWrapper> is something that I can't tell you how to do without seeing your controller, but it should be fairly simple for you to modify your existing code from here.

1
  • Thanks, @DerekF for the detailed answer. I really appreciate your help :) Mar 8, 2017 at 19:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .