function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Exporting to multiple excel worksheets

I am working on putting together a VF page that will export a parent record to the first worksheet in an excel document and a related list of child records to the second tab.  Using this great post from Neeraj Gupta,, I'm able to create the worksheet, but unable to write data to the worksheets.  I'm not well versed in XML so am having trouble seeing where the issue is. The VF Code and Controller Code I"m using as a proof of concept is below.    


VF Code: 

<apex:page id="pg" standardStylesheets="false" standardController="Account" extensions="controllerClass" contenttype="application/">
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">

  <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
        <Style ss:ID="Default" ss:Name="Normal">
            <Alignment ss:Vertical="Bottom"/>
        <Style ss:ID="s23">
          <Font x:Family="Swiss" ss:Bold="1"/>
        <Style ss:ID="s22">
          <Alignment ss:Vertical="Bottom" ss:WrapText="1"/>

  <Worksheet ss:Name="Account">
    <Table >
    <Row ss:StyleID="s23">
        <Cell><Data ss:Type="String">
                <apex:outputText escape="false" value="{!HTMLENCODE("Account Name")}"/>
 <!-- Repeat and create data -->
 <apex:repeat value="{!acct}" var="row">
        <Cell ss:StyleID="s22">
            <Data ss:Type="String">
                <apex:outputText escape="false" value="{!HTMLENCODE(row.Name)}"/>

  <Worksheet ss:Name="Contacts">
    <Table >
    <Row ss:StyleID="s23">
        <Cell><Data ss:Type="String"><apex:outputText escape="false" value="{!HTMLENCODE("First Name")}"/></Data></Cell> 
        <Cell><Data ss:Type="String"><apex:outputText escape="false" value="{!HTMLENCODE("Last Name")}"/></Data></Cell> 
 <!-- Repeat and create rows-->
    <!-- <apex:repeat value="{!cs}" var="2row">-->
     <Cell ss:StyleID="s22"><Data ss:Type="String"><apex:outputText escape="false" value="{!HTMLENCODE(2row.FirstName)}"/></Data></Cell>
     <Cell ss:StyleID="s22"><Data ss:Type="String"><apex:outputText escape="false" value="{!HTMLENCODE(2row.LastName)}"/></Data></Cell>
<apex:outputText value="{!endfile}" escape="false"/>


public without sharing class controllerClass{
  public string xmlheader {get;set;}
  public string endfile{get;set;}
  public Account acct{get;set;}
  public List<Contact> cs{get;set;}
  public controllerClass() {
    //VF page gives some issues directly using the below code there, so wrap up in variable
    xmlheader ='<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?>';
    endfile = '</Workbook>';
     public controllerClass(ApexPages.StandardController stdController) {
        this.acct = (Account)stdController.getRecord();
    public Account getAcct(){
        return acct;
    public List<Contact> getCs(){
        cs = [SELECT id, FirstName, LastName, Email, AccountId FROM Contact WHERE AccountId =];
        return cs;



I hope you solved this.

If not you are using two constructors in the controller class in which only one class is called initially when the page is loaded.

so you have to remove one of the constructor. 

it looks like this 

public controllerClass1(ApexPages.StandardController controller) {
        xmlheader ='<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?>';
        endfile = '</Workbook>';
         this.acct = (Account)controller.getRecord();
        acct = [select Name,Id from Account where Id =:acct.Id];
        cs = [SELECT id, FirstName, LastName,Name, Email, AccountId FROM Contact WHERE AccountId =];

let me know if you didn't solve this