locked
Reg: Adding paragraph and text to new page in docx RRS feed

  • Question

  • hi,

    How to create a new page in docx of the existing docx, using open xml sdk 2.0, and insert a new content into the newly created page. and also how to create header and footer[having pagination] via code using open xml sdk.

     

    regards

    vimal


    regards Vimal
    Tuesday, December 13, 2011 3:54 PM

Answers

  • Hi Vimal,

    Thank you for posting.

    I have tried to make the following code which can meet with your reqirement:

    using DocumentFormat.OpenXml.Packaging;
    using System.IO;
    using DocumentFormat.OpenXml.Wordprocessing;
     
    namespace OpenXmlAddParagraphsToNewPage
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (File.Exists("copy.docx"))
                {
                    File.Delete("copy.docx");
                }
     
                File.Copy("InsertNewPageAndParagraphs.docx""copy.docx");
                using (WordprocessingDocument doc = WordprocessingDocument.Open("copy.docx"true))
                {
                    var body = doc.MainDocumentPart.Document.Body;
     
                    Paragraph newPara = new Paragraph(new Run
                         (new Break() { Type = BreakValues.Page },
                         new Text("text on the new page")));
     
                    body.Append(newPara);
     
                    AddHeader(doc);
                    AddFooter(doc);
                    doc.MainDocumentPart.Document.Save();
                }
            }
     
            private static void AddFooter(WordprocessingDocument doc)
            {
                // Declare a string for the header text.
                string newFooterText =
                  "New footer via Open XML Format SDK 2.0 classes";
     
                // Get the main document part.
                MainDocumentPart mainDocPart = doc.MainDocumentPart;
     
                // Delete the existing footer parts.
                mainDocPart.DeleteParts(mainDocPart.FooterParts);
     
                // Create a new footer part and get its relationship id.
                FooterPart newFooterPart = mainDocPart.AddNewPart<FooterPart>();
                string rId = mainDocPart.GetIdOfPart(newFooterPart);
     
                // Call the GeneratePageFooterPart helper method, passing in
                // the footer text, to create the footer markup and then save
                // that markup to the footer part.
                GeneratePageFooterPart(newFooterText).Save(newFooterPart);
     
                // Loop through all section properties in the document
                // which is where footer references are defined.
                foreach (SectionProperties sectProperties in
                  mainDocPart.Document.Descendants<SectionProperties>())
                {
                    //  Delete any existing references to footers.
                    foreach (FooterReference footerReference in
                      sectProperties.Descendants<FooterReference>())
                        sectProperties.RemoveChild(footerReference);
     
                    //  Create a new footer reference that points to the new
                    // footer part and add it to the section properties.
                    FooterReference newFooterReference =
                      new FooterReference() { Id = rId, Type = HeaderFooterValues.Default };
                    sectProperties.Append(newFooterReference);
                }
                
                //  Save the changes to the main document part.
                mainDocPart.Document.Save();
            }
     
            private static void AddHeader(WordprocessingDocument doc)
            {
                // Declare a string for the header text.
                string newHeaderText =
                  "New header via Open XML Format SDK 2.0 classes";
     
     
                // Get the main document part.
                MainDocumentPart mainDocPart = doc.MainDocumentPart;
     
                // Delete the existing header parts.
                mainDocPart.DeleteParts(mainDocPart.HeaderParts);
     
                // Create a new header part and get its relationship id.
                HeaderPart newHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
                string rId = mainDocPart.GetIdOfPart(newHeaderPart);
     
                // Call the GeneratePageHeaderPart helper method, passing in
                // the header text, to create the header markup and then save
                // that markup to the header part.
                GeneratePageHeaderPart(newHeaderText).Save(newHeaderPart);
     
                // Loop through all section properties in the document
                // which is where header references are defined.
                foreach (SectionProperties sectProperties in
                  mainDocPart.Document.Descendants<SectionProperties>())
                {
                    //  Delete any existing references to headers.
                    foreach (HeaderReference headerReference in
                      sectProperties.Descendants<HeaderReference>())
                        sectProperties.RemoveChild(headerReference);
     
                    //  Create a new header reference that points to the new
                    // header part and add it to the section properties.
                    HeaderReference newHeaderReference =
                      new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default };
                    sectProperties.Append(newHeaderReference);
                }
     
                //  Save the changes to the main document part.
                //mainDocPart.Document.Save();
     
            }
     
            // Creates an header instance and adds its children.
            private static Header GeneratePageHeaderPart(string HeaderText)
            {
                // set the position to be the center
                PositionalTab pTab = new PositionalTab()
                {
                    Alignment = AbsolutePositionTabAlignmentValues.Center,
                    RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                    Leader = AbsolutePositionTabLeaderCharValues.None
                };
     
                var element =
                  new Header(
                    new Paragraph(
                      new ParagraphProperties(
                        new ParagraphStyleId() { Val = "Header" }),
                      new Run(pTab,
                        new Text(HeaderText))
                    )
                  );
     
                return element;
            }
     
            // Creates an Footer instance and adds its children.
            private static Footer GeneratePageFooterPart(string FooterText)
            {
                PositionalTab pTab = new PositionalTab()
                {
                    Alignment = AbsolutePositionTabAlignmentValues.Center,
                    RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                    Leader = AbsolutePositionTabLeaderCharValues.None
                };
     
                var elment =
                    new Footer(
                        new Paragraph(
                            new ParagraphProperties(
                                new ParagraphStyleId() { Val = "Footer" }),
                            new Run(pTab,
                                new Text(FooterText))
                                    )
                                );
                return elment;
            }
        }
    }
    

    And here is the screenshot after running:

    Hope this  can help you adn just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    • Proposed as answer by Bruce Song Wednesday, December 21, 2011 4:41 AM
    • Marked as answer by Bruce Song Thursday, December 22, 2011 6:52 AM
    Wednesday, December 14, 2011 8:57 AM

All replies

  • Hi Vimal,

    Thank you for posting.

    I have tried to make the following code which can meet with your reqirement:

    using DocumentFormat.OpenXml.Packaging;
    using System.IO;
    using DocumentFormat.OpenXml.Wordprocessing;
     
    namespace OpenXmlAddParagraphsToNewPage
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (File.Exists("copy.docx"))
                {
                    File.Delete("copy.docx");
                }
     
                File.Copy("InsertNewPageAndParagraphs.docx""copy.docx");
                using (WordprocessingDocument doc = WordprocessingDocument.Open("copy.docx"true))
                {
                    var body = doc.MainDocumentPart.Document.Body;
     
                    Paragraph newPara = new Paragraph(new Run
                         (new Break() { Type = BreakValues.Page },
                         new Text("text on the new page")));
     
                    body.Append(newPara);
     
                    AddHeader(doc);
                    AddFooter(doc);
                    doc.MainDocumentPart.Document.Save();
                }
            }
     
            private static void AddFooter(WordprocessingDocument doc)
            {
                // Declare a string for the header text.
                string newFooterText =
                  "New footer via Open XML Format SDK 2.0 classes";
     
                // Get the main document part.
                MainDocumentPart mainDocPart = doc.MainDocumentPart;
     
                // Delete the existing footer parts.
                mainDocPart.DeleteParts(mainDocPart.FooterParts);
     
                // Create a new footer part and get its relationship id.
                FooterPart newFooterPart = mainDocPart.AddNewPart<FooterPart>();
                string rId = mainDocPart.GetIdOfPart(newFooterPart);
     
                // Call the GeneratePageFooterPart helper method, passing in
                // the footer text, to create the footer markup and then save
                // that markup to the footer part.
                GeneratePageFooterPart(newFooterText).Save(newFooterPart);
     
                // Loop through all section properties in the document
                // which is where footer references are defined.
                foreach (SectionProperties sectProperties in
                  mainDocPart.Document.Descendants<SectionProperties>())
                {
                    //  Delete any existing references to footers.
                    foreach (FooterReference footerReference in
                      sectProperties.Descendants<FooterReference>())
                        sectProperties.RemoveChild(footerReference);
     
                    //  Create a new footer reference that points to the new
                    // footer part and add it to the section properties.
                    FooterReference newFooterReference =
                      new FooterReference() { Id = rId, Type = HeaderFooterValues.Default };
                    sectProperties.Append(newFooterReference);
                }
                
                //  Save the changes to the main document part.
                mainDocPart.Document.Save();
            }
     
            private static void AddHeader(WordprocessingDocument doc)
            {
                // Declare a string for the header text.
                string newHeaderText =
                  "New header via Open XML Format SDK 2.0 classes";
     
     
                // Get the main document part.
                MainDocumentPart mainDocPart = doc.MainDocumentPart;
     
                // Delete the existing header parts.
                mainDocPart.DeleteParts(mainDocPart.HeaderParts);
     
                // Create a new header part and get its relationship id.
                HeaderPart newHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
                string rId = mainDocPart.GetIdOfPart(newHeaderPart);
     
                // Call the GeneratePageHeaderPart helper method, passing in
                // the header text, to create the header markup and then save
                // that markup to the header part.
                GeneratePageHeaderPart(newHeaderText).Save(newHeaderPart);
     
                // Loop through all section properties in the document
                // which is where header references are defined.
                foreach (SectionProperties sectProperties in
                  mainDocPart.Document.Descendants<SectionProperties>())
                {
                    //  Delete any existing references to headers.
                    foreach (HeaderReference headerReference in
                      sectProperties.Descendants<HeaderReference>())
                        sectProperties.RemoveChild(headerReference);
     
                    //  Create a new header reference that points to the new
                    // header part and add it to the section properties.
                    HeaderReference newHeaderReference =
                      new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default };
                    sectProperties.Append(newHeaderReference);
                }
     
                //  Save the changes to the main document part.
                //mainDocPart.Document.Save();
     
            }
     
            // Creates an header instance and adds its children.
            private static Header GeneratePageHeaderPart(string HeaderText)
            {
                // set the position to be the center
                PositionalTab pTab = new PositionalTab()
                {
                    Alignment = AbsolutePositionTabAlignmentValues.Center,
                    RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                    Leader = AbsolutePositionTabLeaderCharValues.None
                };
     
                var element =
                  new Header(
                    new Paragraph(
                      new ParagraphProperties(
                        new ParagraphStyleId() { Val = "Header" }),
                      new Run(pTab,
                        new Text(HeaderText))
                    )
                  );
     
                return element;
            }
     
            // Creates an Footer instance and adds its children.
            private static Footer GeneratePageFooterPart(string FooterText)
            {
                PositionalTab pTab = new PositionalTab()
                {
                    Alignment = AbsolutePositionTabAlignmentValues.Center,
                    RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                    Leader = AbsolutePositionTabLeaderCharValues.None
                };
     
                var elment =
                    new Footer(
                        new Paragraph(
                            new ParagraphProperties(
                                new ParagraphStyleId() { Val = "Footer" }),
                            new Run(pTab,
                                new Text(FooterText))
                                    )
                                );
                return elment;
            }
        }
    }
    

    And here is the screenshot after running:

    Hope this  can help you adn just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    • Proposed as answer by Bruce Song Wednesday, December 21, 2011 4:41 AM
    • Marked as answer by Bruce Song Thursday, December 22, 2011 6:52 AM
    Wednesday, December 14, 2011 8:57 AM
  • hi

    thanks for reply,

     I got it worked , can you please tell me how can i get the page number  in footer and have a line after header and above footer as styling.

     


    regards Vimal
    Thursday, December 15, 2011 10:32 AM
  • Hi Vimal,

    Please refer to the following code snippets about your requirement:

     

     

     // Creates an Footer instance and adds its children.
            public Footer GenerateFooter()
            {
                Footer footer1 = new Footer(){ MCAttributes = new MarkupCompatibilityAttributes(){ Ignorable = "w14 wp14" }  };
                footer1.AddNamespaceDeclaration("wpc", "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas");
                footer1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                footer1.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
                footer1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                footer1.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
                footer1.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
                footer1.AddNamespaceDeclaration("wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
                footer1.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
                footer1.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
                footer1.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                footer1.AddNamespaceDeclaration("w14", "http://schemas.microsoft.com/office/word/2010/wordml");
                footer1.AddNamespaceDeclaration("wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup");
                footer1.AddNamespaceDeclaration("wpi", "http://schemas.microsoft.com/office/word/2010/wordprocessingInk");
                footer1.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
                footer1.AddNamespaceDeclaration("wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");
    
                Paragraph paragraph1 = new Paragraph(){ RsidParagraphAddition = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties1 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId(){ Val = "a4" };
    
                ParagraphBorders paragraphBorders1 = new ParagraphBorders();
                BottomBorder bottomBorder1 = new BottomBorder(){ Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)6U, Space = (UInt32Value)1U };
    
                paragraphBorders1.Append(bottomBorder1);
                Justification justification1 = new Justification(){ Val = JustificationValues.Center };
    
                ParagraphMarkRunProperties paragraphMarkRunProperties1 = new ParagraphMarkRunProperties();
                RunFonts runFonts1 = new RunFonts(){ Hint = FontTypeHintValues.EastAsia };
    
                paragraphMarkRunProperties1.Append(runFonts1);
    
                paragraphProperties1.Append(paragraphStyleId1);
                paragraphProperties1.Append(paragraphBorders1);
                paragraphProperties1.Append(justification1);
                paragraphProperties1.Append(paragraphMarkRunProperties1);
    
                paragraph1.Append(paragraphProperties1);
    
                Paragraph paragraph2 = new Paragraph(){ RsidParagraphAddition = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties2 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId2 = new ParagraphStyleId(){ Val = "a4" };
                Justification justification2 = new Justification(){ Val = JustificationValues.Center };
    
                ParagraphMarkRunProperties paragraphMarkRunProperties2 = new ParagraphMarkRunProperties();
                RunFonts runFonts2 = new RunFonts(){ Hint = FontTypeHintValues.EastAsia };
    
                paragraphMarkRunProperties2.Append(runFonts2);
    
                paragraphProperties2.Append(paragraphStyleId2);
                paragraphProperties2.Append(justification2);
                paragraphProperties2.Append(paragraphMarkRunProperties2);
    
                paragraph2.Append(paragraphProperties2);
    
                Paragraph paragraph3 = new Paragraph(){ RsidParagraphAddition = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties3 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId3 = new ParagraphStyleId(){ Val = "a4" };
                Justification justification3 = new Justification(){ Val = JustificationValues.Center };
    
                paragraphProperties3.Append(paragraphStyleId3);
                paragraphProperties3.Append(justification3);
    
                SdtRun sdtRun1 = new SdtRun();
    
                SdtProperties sdtProperties1 = new SdtProperties();
                SdtId sdtId1 = new SdtId(){ Val = 1180236299 };
    
                SdtContentDocPartObject sdtContentDocPartObject1 = new SdtContentDocPartObject();
                DocPartGallery docPartGallery1 = new DocPartGallery(){ Val = "Page Numbers (Bottom of Page)" };
                DocPartUnique docPartUnique1 = new DocPartUnique();
    
                sdtContentDocPartObject1.Append(docPartGallery1);
                sdtContentDocPartObject1.Append(docPartUnique1);
    
                sdtProperties1.Append(sdtId1);
                sdtProperties1.Append(sdtContentDocPartObject1);
    
                SdtContentRun sdtContentRun1 = new SdtContentRun();
    
                Run run1 = new Run();
                FieldChar fieldChar1 = new FieldChar(){ FieldCharType = FieldCharValues.Begin };
    
                run1.Append(fieldChar1);
    
                Run run2 = new Run();
                FieldCode fieldCode1 = new FieldCode();
                fieldCode1.Text = "PAGE   \\* MERGEFORMAT";
    
                run2.Append(fieldCode1);
    
                Run run3 = new Run();
                FieldChar fieldChar2 = new FieldChar(){ FieldCharType = FieldCharValues.Separate };
    
                run3.Append(fieldChar2);
    
                Run run4 = new Run(){ RsidRunProperties = "00794274" };
    
                RunProperties runProperties1 = new RunProperties();
                NoProof noProof1 = new NoProof();
                Languages languages1 = new Languages(){ Val = "zh-CN" };
    
                runProperties1.Append(noProof1);
                runProperties1.Append(languages1);
                Text text1 = new Text();
                text1.Text = "1";
    
                run4.Append(runProperties1);
                run4.Append(text1);
    
                Run run5 = new Run();
                FieldChar fieldChar3 = new FieldChar(){ FieldCharType = FieldCharValues.End };
    
                run5.Append(fieldChar3);
    
                sdtContentRun1.Append(run1);
                sdtContentRun1.Append(run2);
                sdtContentRun1.Append(run3);
                sdtContentRun1.Append(run4);
                sdtContentRun1.Append(run5);
    
                sdtRun1.Append(sdtProperties1);
                sdtRun1.Append(sdtContentRun1);
    
                paragraph3.Append(paragraphProperties3);
                paragraph3.Append(sdtRun1);
    
                Paragraph paragraph4 = new Paragraph(){ RsidParagraphMarkRevision = "00794274", RsidParagraphAddition = "00794274", RsidParagraphProperties = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties4 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId4 = new ParagraphStyleId(){ Val = "a4" };
    
                paragraphProperties4.Append(paragraphStyleId4);
    
                paragraph4.Append(paragraphProperties4);
    
                footer1.Append(paragraph1);
                footer1.Append(paragraph2);
                footer1.Append(paragraph3);
                footer1.Append(paragraph4);
                return footer1;
            }
    
    
    

     

     

    
    // Creates an Header instance and adds its children.
            public Header GenerateHeader()
            {
                Header header1 = new Header(){ MCAttributes = new MarkupCompatibilityAttributes(){ Ignorable = "w14 wp14" }  };
                header1.AddNamespaceDeclaration("wpc", "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas");
                header1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                header1.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
                header1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                header1.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
                header1.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
                header1.AddNamespaceDeclaration("wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
                header1.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
                header1.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
                header1.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                header1.AddNamespaceDeclaration("w14", "http://schemas.microsoft.com/office/word/2010/wordml");
                header1.AddNamespaceDeclaration("wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup");
                header1.AddNamespaceDeclaration("wpi", "http://schemas.microsoft.com/office/word/2010/wordprocessingInk");
                header1.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
                header1.AddNamespaceDeclaration("wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");
    
                Paragraph paragraph1 = new Paragraph(){ RsidParagraphAddition = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties1 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId(){ Val = "a3" };
    
                ParagraphBorders paragraphBorders1 = new ParagraphBorders();
                BottomBorder bottomBorder1 = new BottomBorder(){ Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)6U, Space = (UInt32Value)1U };
    
                paragraphBorders1.Append(bottomBorder1);
    
                ParagraphMarkRunProperties paragraphMarkRunProperties1 = new ParagraphMarkRunProperties();
                RunFonts runFonts1 = new RunFonts(){ Hint = FontTypeHintValues.EastAsia };
    
                paragraphMarkRunProperties1.Append(runFonts1);
    
                paragraphProperties1.Append(paragraphStyleId1);
                paragraphProperties1.Append(paragraphBorders1);
                paragraphProperties1.Append(paragraphMarkRunProperties1);
    
                Run run1 = new Run();
                Text text1 = new Text();
                text1.Text = "T";
    
                run1.Append(text1);
    
                Run run2 = new Run();
    
                RunProperties runProperties1 = new RunProperties();
                RunFonts runFonts2 = new RunFonts(){ Hint = FontTypeHintValues.EastAsia };
    
                runProperties1.Append(runFonts2);
                Text text2 = new Text();
                text2.Text = "his is header";
    
                run2.Append(runProperties1);
                run2.Append(text2);
    
                paragraph1.Append(paragraphProperties1);
                paragraph1.Append(run1);
                paragraph1.Append(run2);
    
                Paragraph paragraph2 = new Paragraph(){ RsidParagraphAddition = "00794274", RsidRunAdditionDefault = "00794274" };
    
                ParagraphProperties paragraphProperties2 = new ParagraphProperties();
                ParagraphStyleId paragraphStyleId2 = new ParagraphStyleId(){ Val = "a3" };
    
                paragraphProperties2.Append(paragraphStyleId2);
    
                paragraph2.Append(paragraphProperties2);
    
                header1.Append(paragraph1);
                header1.Append(paragraph2);
                return header1;
            }
    
    
    


    The two code snippets can achieve your requirement and you can utilize them and simplify some parts(eg. remove those namespaces). Hope this can help you and just feel free to follow up after you have tried.

    Best Regards,  


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    • Edited by Bruce Song Tuesday, December 20, 2011 9:05 AM
    Tuesday, December 20, 2011 9:04 AM
  • hi

    Thanks for reply,

    I got it worked thank you very much.


    regards Vimal
    Tuesday, December 20, 2011 2:12 PM