• 【转】【OpenXml】OpenXml操作Word的一些操作总结


    OpenXml相对于用MS提供的COM组件来生成WORD,有如下优势:

    1.相对于MS 的COM组件,因为版本带来的不兼容问题,及各种会生成WORD半途会崩溃的问题.

    2.对比填满一张30多页的WORD来说(包含图,表等),用COM组件来生成会占用20秒,Openxml1秒.

    3.MS Word软件太贵了,你的客户装的是开源WORD,如LibreOffice,OpenOffice.这样你就只能用Openxml生成的WORD文档,各种支持MS Word都能打开,避免客户机器上安装MS Word.

    简单来说OpenXml的各个操作.

    首先用OpenXml打开一张报表.

    public void CreateOpenXMLFile(string filePath)  
            {  
                using (WordprocessingDocument objWordDocument = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))  
                {  
                    MainDocumentPart objMainDocumentPart = objWordDocument.AddMainDocumentPart();  
                    objMainDocumentPart.Document = new Document(new Body());  
                    Body objBody = objMainDocumentPart.Document.Body;  
                    //创建一些需要用到的样式,如标题3,标题4,在OpenXml里面,这些样式都要自己来创建的   
                    //ReportExport.CreateParagraphStyle(objWordDocument);  
                    SectionProperties sectionProperties = new SectionProperties();  
                    PageSize pageSize = new PageSize();  
                    PageMargin pageMargin = new PageMargin();  
                    Columns columns = new Columns() { Space = "220" };//720  
                    DocGrid docGrid = new DocGrid() { LinePitch = 100 };//360  
                    //创建页面的大小,页距,页面方向一些基本的设置,如A4,B4,Letter,   
                    //GetPageSetting(PageSize,PageMargin);  
      
                    //在这里填充各个Paragraph,与Table,页面上第一级元素就是段落,表格.  
                    objBody.Append(new Paragraph());  
                    objBody.Append(new Table());  
                    objBody.Append(new Paragraph());  
      
                    //我会告诉你这里的顺序很重要吗?下面才是把上面那些设置放到Word里去.(大家可以试试把这下面的代码放上面,会不会出现打开openxml文件有误,因为内容有误)  
                    sectionProperties.Append(pageSize, pageMargin, columns, docGrid);  
                    objBody.Append(sectionProperties);  
                      
                    //如果有页眉,在这里添加页眉.  
                    if (IsAddHead)  
                    {  
                        //添加页面,如果有图片,这个图片和上面添加在objBody方式有点不一样,这里搞了好久.  
                        //ReportExport.AddHeader(objMainDocumentPart, image);  
                    }  
                    objMainDocumentPart.Document.Save();  
                }  
            }  

    发现上面有点注解说错,那个顺序不影响Word,但是影响如LibreOffice软件打开后看到的格式不正确.改里面太麻烦,直接在这说了.

    从这个总纲里,把上面的各个步骤再来仔细说下.

    首先是在Openxml创建标题3,标题4.

    // 为文档创建段落样式  

      public static void CreateParagraphStyle(WordprocessingDocument doc)  
            {  
                // 进入文档控制样式部分  
                StyleDefinitionsPart styleDefinitionsPart;  
                styleDefinitionsPart = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();  
                Styles root = new Styles();  
                root.Save(styleDefinitionsPart);  
      
                Styles styles = styleDefinitionsPart.Styles;  
                if (styles == null)  
                {  
                    styleDefinitionsPart.Styles = new Styles();  
                    styleDefinitionsPart.Styles.Save();  
                }  
      
                Style style3 = CreateTitleStyle(3);  
                Style style4 = CreateTitleStyle(4);  
                // 把样式添加入文档中  
                styles.Append(style3);  
                styles.Append(style4);  
            }  
      
            private static Style CreateTitleStyle(int titleIndex)  
            {  
                string titleID = titleIndex.ToString();  
                string rsid = string.Empty;  
                string before = string.Empty;  
                string after = string.Empty;  
                string line = string.Empty;  
                string val = string.Empty;  
                int outline = titleIndex - 1;  
                if (titleIndex == 3)  
                {  
                    rsid = "00BA1E98";  
                    before = "130";//"260"  
                    after = "0";  
                    line = "286";//"416"  
                    val = "32";  
      
                }  
                else if (titleIndex == 4)  
                {  
                    rsid = "00BA1E98";  
                    before = "88";  
                    after = "0";  
                    line = "288";//"376"  
                    val = "28";  
                }  
      
                Style style2 = new Style() { Type = StyleValues.Paragraph, StyleId = titleID };  
                StyleName styleName2 = new StyleName() { Val = "heading " + titleID };  
                BasedOn basedOn1 = new BasedOn() { Val = "a" };  
                NextParagraphStyle nextParagraphStyle1 = new NextParagraphStyle() { Val = "a" };  
                LinkedStyle linkedStyle1 = new LinkedStyle() { Val = titleID + "Char" };  
                UIPriority uIPriority1 = new UIPriority() { Val = 9 };  
                PrimaryStyle primaryStyle2 = new PrimaryStyle();  
                Rsid rsid2 = new Rsid() { Val = rsid };  
                style2.Append(styleName2);  
                style2.Append(basedOn1);  
                style2.Append(nextParagraphStyle1);  
                style2.Append(linkedStyle1);  
                style2.Append(uIPriority1);  
                style2.Append(primaryStyle2);  
                style2.Append(rsid2);  
      
                StyleParagraphProperties styleParagraphProperties2 = new StyleParagraphProperties();  
                KeepNext keepNext1 = new KeepNext();  
                KeepLines keepLines1 = new KeepLines();  
                SpacingBetweenLines spacingBetweenLines1 = new SpacingBetweenLines() { Before = before, After = after, Line = line, LineRule = LineSpacingRuleValues.Auto };  
                OutlineLevel outlineLevel1 = new OutlineLevel() { Val = outline };  
                styleParagraphProperties2.Append(keepNext1);  
                styleParagraphProperties2.Append(keepLines1);  
                styleParagraphProperties2.Append(spacingBetweenLines1);  
                styleParagraphProperties2.Append(outlineLevel1);  
                style2.Append(styleParagraphProperties2);  
      
                StyleRunProperties styleRunProperties1 = new StyleRunProperties();  
                Bold bold1 = new Bold();  
                BoldComplexScript boldComplexScript1 = new BoldComplexScript();  
                // Kern kern2 = new Kern() { Val = (UInt32)44U };  
                FontSize fontSize2 = new FontSize() { Val = val };  
                FontSizeComplexScript fontSizeComplexScript2 = new FontSizeComplexScript() { Val = val };  
                styleRunProperties1.Append(bold1);  
                styleRunProperties1.Append(boldComplexScript1);  
                //styleRunProperties1.Append(kern2);  
                styleRunProperties1.Append(fontSize2);  
                styleRunProperties1.Append(fontSizeComplexScript2);  
                style2.Append(styleRunProperties1);  
                return style2;  
            }  

    然后是对页面大小,页面方向,页距设置.(懒的和报表里的一个个对应,里面的页距有很多大家可以精确设置.)

    public static void GetPageSetting(ref PageSize pageSize, ref PageMargin pageMargin)  
            {  
                bool val = IsPaperOrientation;  
                string str_paperSize = "Letter";//A4,B4  
                UInt32Value width = 15840U;  
                UInt32Value height = 12240U;  
                int top = 1440;  
                UInt32Value left = 1440U;  
                if (str_paperSize == "A4")  
                {  
                    width = 16840U;  
                    height = 11905U;  
                }  
                else if (str_paperSize == "B4")  
                {  
                    width = 20636U;  
                    height = 14570U;  
                }  
      
                if (!val)  
                {  
                    UInt32Value sweep = width;  
                    width = height;  
                    height = sweep;  
      
                    int top_sweep = top;  
                    top = (int)left.Value;  
                    left = (uint)top_sweep;  
                }  
      
                pageSize.Width = width;  
                pageSize.Height = height;  
                pageSize.Orient = new EnumValue<PageOrientationValues>(val ? PageOrientationValues.Landscape : PageOrientationValues.Portrait);  
      
                pageMargin.Top = top;  
                pageMargin.Bottom = top;  
                pageMargin.Left = left;  
                pageMargin.Right = left;  
                pageMargin.Header = (UInt32Value)720U;  
                pageMargin.Footer = (UInt32Value)720U;  
                pageMargin.Gutter = (UInt32Value)0U;  
            }  

    然后重点来了,大家对各元素如何在OpenXml添加的.

    我先说下,在Openxml里相关元素的关系,在Word里,按一下Enter,转一行,对应的一行元素就是Paragraph,那如果一行文字在里面如何存放.Paragraph->Run->Text,图表Paragraph->Run->Drawing,表格Table->TableRow->TableCell->Paragraph->Run->Text与Drawing.在关系上说,还是很简洁的.来看一下具体的操作,我们先定义一个类.对应OpenXML里的基本样式设置.

    public class ReportCommon  
        {  
            public const float defaultSize = 12f;  
            public const float H1 = 20f;  
            public const float H3 = 16f;  
            public const float H4 = 14f;  
            private string text = string.Empty;  
      
            public ReportCommon()  
            {  
                Alignment = -1;  
                Size = defaultSize;  
            }  
      
            //规定-1左对齐,0中间,1右对齐  
            public int Alignment { get; set; }  
      
            public virtual float Size { get; set; }  
      
            public string Text { get; set; }  
      
            public virtual bool IsBold { get; set; }  
        }  

    其中我定义这个类的三个子类,分别是ReportValue:主要是这种A: B,ReportImage:包含一个图片的路径.ReportText:只有一个文本.

    private static List<Run> GetRuns(ReportCommon common)  
            {  
                List<Run> runs = new List<Run>();  
                if (common is ReportValue)  
                {  
                    ReportValue reportvalue = common as ReportValue;  
                    Run r = new Run();  
                    RunProperties rP = GetRunProperties(reportvalue, true);  
                    r.Append(rP);  
                    string text = reportvalue.Text;  
                    if (text.EndsWith(":"))  
                        text = text + " ";  
                    if (!text.EndsWith(": "))  
                        text = text + ": ";  
                    Text t = CreateText(text);  
                    r.Append(t);  
                    runs.Add(r);  
      
                    r = new Run();  
                    rP = GetRunProperties(reportvalue, false);  
                    r.Append(rP);  
                    r.Append(CreateText(reportvalue.Value));  
                    runs.Add(r);  
                }  
                else if (common is ReportImage)  
                {  
                    ReportImage reportImage = common as ReportImage;  
                    Run r = new Run();  
                    RunProperties rP = GetRunProperties(reportImage);  
                    Drawing image = GetImageToBody(reportImage.RId, reportImage.Width * 600, reportImage.Height * 800);  
                    //Drawing image = new Drawing();  
                    //image.Append(new A.Blip() { Embed = new StringValue(reportImage.RId) });  
                    r.Append(rP);  
                    r.Append(image);  
                    runs.Add(r);  
                }  
                else if (common is ReportText)  
                {  
                    Run r = new Run();  
                    RunProperties rP = GetRunProperties(common);  
                    r.Append(rP);  
                    r.Append(CreateText(common.Text));  
                    runs.Add(r);  
                }  
                return runs;  
            } 

    看了这里,问题是不是越来越多.图片具体操作先不说.上面的RunProperties,与CreateText分别是指什么.

    RunProperties是指包含这段Text,你要设置的一些字体大小,颜色,文本对齐设置.

    而CreateText是因为我们在Openxml你在后面加个空格,而会给你过滤掉,空格要对应到XML的具体设置,看如下代码.

    public static RunProperties GetRunProperties(ReportCommon common, bool bBold = false)  
            {  
                RunProperties rPr = new RunProperties();  
                //Color color = new Color() { Val = "FF0000" }; // the color is red  
                RunFonts rFont = new RunFonts();  
                rFont.Ascii = "Arial"; // the font is Arial  
                //rPr.Append(color);  
                //rPr.Append(rFont);  
                if (common.IsBold || bBold)  
                    rPr.Append(new Bold()); // it is Bold  
                //TextAlignment   
                rPr.Append(new FontSize() { Val = new StringValue((common.Size * 2).ToString()) }); //font size (in 1/72 of an inch)  
                return rPr;  
            }  
      private static Text CreateText(string text)  
            {  
                if (text == null)  
                    text = string.Empty;  
                Text t = new Text(text);  
                if (text.EndsWith(" "))  
                {  
                    t.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Preserve);  
                }  
                if (text.StartsWith(" "))  
                {  
                    t.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Default);  
                }  
                return t;  
            }  

    不知这么多代码大家看烦没,因为我这人喜欢不是业务与大纲的事,都喜欢直接看代码来说,比人讲的清楚.所以讲的时候也喜欢,直接上代码.废话不说了,说下图片的问题,Openxml插入图片比较麻烦,先贴一段代码.

    private static Drawing GetImageToBody(string relationshipId, int x = 914400, int y = 360000)  
            {  
                // Define the reference of the image.  
                var element =  
                     new Drawing(  
                         new DW.Inline(  
                             new DW.Extent() { Cx = x, Cy = y },  
                             new DW.EffectExtent()  
                             {  
                                 LeftEdge = 0L,  
                                 TopEdge = 0L,  
                                 RightEdge = 0L,  
                                 BottomEdge = 0L  
                             },  
                             new DW.DocProperties()  
                             {  
                                 Id = (UInt32Value)1U,  
                                 Name = "Picture 1"  
                             },  
                             new DW.NonVisualGraphicFrameDrawingProperties(  
                                 new A.GraphicFrameLocks() { NoChangeAspect = true }),  
                             new A.Graphic(  
                                 new A.GraphicData(  
                                     new PIC.Picture(  
                                         new PIC.NonVisualPictureProperties(  
                                             new PIC.NonVisualDrawingProperties()  
                                             {  
                                                 Id = (UInt32Value)0U,  
                                                 Name = "New Bitmap Image.jpg"  
                                             },  
                                             new PIC.NonVisualPictureDrawingProperties()),  
                                         new PIC.BlipFill(  
                                             new A.Blip(  
                                                 new A.BlipExtensionList(  
                                                     new A.BlipExtension()  
                                                     {  
                                                         Uri =  
                                                           "{28A0092B-C50C-407E-A947-70E740481C1C}"  
                                                     })  
                                             )  
                                             {  
                                                 Embed = relationshipId,  
                                                 CompressionState =  
                                                 A.BlipCompressionValues.Print  
                                             },  
                                             new A.Stretch(  
                                                 new A.FillRectangle())),  
                                         new PIC.ShapeProperties(  
                                             new A.Transform2D(  
                                                 new A.Offset() { X = 0L, Y = 0L },  
                                                 new A.Extents() { Cx = x, Cy = y }),  
                                             new A.PresetGeometry(  
                                                 new A.AdjustValueList()  
                                             ) { Preset = A.ShapeTypeValues.Rectangle }))  
                                 ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })  
                         )  
                         {  
                             DistanceFromTop = (UInt32Value)0U,  
                             DistanceFromBottom = (UInt32Value)0U,  
                             DistanceFromLeft = (UInt32Value)0U,  
                             DistanceFromRight = (UInt32Value)0U,  
                             EditId = "50D07946"  
                         });  
                // Append the reference to body, the element should be in a Run.  
                var blip = element.Descendants<DocumentFormat.OpenXml.Drawing.Blip>()  
                   .FirstOrDefault<DocumentFormat.OpenXml.Drawing.Blip>();  
                return element;  
            } 

    这段代码里,东东比较多,大家主要看这一节, Embed = relationshipId,也是参数里要求传入的,我们可以这么理解,在OpenXML插入一张电脑的图片,插入数据到word后,word然后把保存这个图片的一个标识量给我们,让我们来用,就是relationshipId.说到这,我们好像还没看如何把一张路径下的图片插入word.如下

    public static void CreateImageRid(ReportImage reportImage, MainDocumentPart objMainDocumentPart)  
            {  
                ImagePartType imagetype = ImagePartType.Jpeg;  
                FileInfo newImg = new FileInfo(reportImage.Value);  
                ImagePart newImgPart = objMainDocumentPart.AddImagePart(imagetype);  
                //插入图片数据到Word里去.  
                using (FileStream stream = newImg.OpenRead())  
                {  
                    newImgPart.FeedData(stream);  
                }  
                //Word返回给我们插入数据的标识符.  
                reportImage.RId = objMainDocumentPart.GetIdOfPart(newImgPart);  
            }  

    这里图片插入有先后关系,要先调用上面这段,插入数据到word,然后才能调用上上段的那段代码来生成Drawing元素.

    大家如果要把图片的宽度,设为当前Word的可用宽度.Int32Value width = (int)(pageSize.Width - pageMargin.Right - pageMargin.Left);

    好吧,大家会发现上上段那里的长度特大,这里发现这里的值要很大才能显现比较好看的图片,一般我在原来的基础宽度*600,基础长度*800.原因吗,我也不清楚,有些猜测,没有验证就不说了,这个要求OpenXML生成报表比较急,我把这几天所有操作先总结一下.后面再来修改,如果有知道的道友,不妨说一下.

    在这里,文字与图片如何生成Paragraph就很简单了.

    public static Paragraph GetParagraph(ReportCommon common)  
            {  
                Paragraph p = new Paragraph();  
                ParagraphProperties pPr = GetParagraphProperties(common);  
                p.Append(pPr);  
                List<Run> run = GetRuns(common);  
                foreach (var r in run)  
                {  
                    p.Append(r);  
                }  
                return p;  
            }  

    好吧,最后说到如何在OpenXML生成一张表.生成图表我用的基础数据是List<List<string>>,上面的ReportTable数据就放在这个里面.当然还有一些基本的定义属性就不说.具体如下看代码.

    public static Table GetParagraph(ReportTable reportTable, Int32Value width)  
            {  
                Table table = new Table();  
                TableProperties tblProp = new TableProperties(  
                    new TableBorders(  
                        new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },  
                        new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },  
                        new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },  
                        new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },  
                        new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },  
                        new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 }  
                     )  
                );  
                tblProp.TableWidth = new TableWidth() { Width = width.ToString(), Type = TableWidthUnitValues.Dxa };  
                table.Append(tblProp);  
                int count = reportTable.Value.Count;  
                int cols = reportTable.Column;  
                int j = 0;  
                foreach (List<string> strs in reportTable.Value)  
                {  
                    TableRow row = new TableRow();  
                    for (int i = 0; i < cols; i++)  
                    {  
                        TableCell cell = new TableCell();  
                        TableCellProperties tableCellProperties = new TableCellProperties();  
                        TableCellMargin margin = new TableCellMargin();  
                        margin.LeftMargin = new LeftMargin() { Width = "100", Type = TableWidthUnitValues.Dxa };  
                        margin.RightMargin = new RightMargin() { Width = "100", Type = TableWidthUnitValues.Dxa };  
                        tableCellProperties.Append(margin);  
                        Paragraph par = new Paragraph();  
                        Run run = new Run();  
                        if (j == 0 && reportTable.IsHaveColumn)  
                        {  
                            RunProperties rPr = new RunProperties();  
                            rPr.Append(new Bold());  
                            run.Append(rPr);  
                        }  
                        if (strs.Count != cols && i >= strs.Count - 1)  
                        {  
                            HorizontalMerge verticalMerge = new HorizontalMerge();  
                            if (i == strs.Count - 1)  
                            {  
                                RunProperties rPr = new RunProperties();  
                                rPr.Append(new Bold());  
                                run.Append(rPr);  
                                verticalMerge.Val = MergedCellValues.Restart;  
                                run.Append(CreateText(strs[i]));  
                            }  
                            else  
                            {  
                                verticalMerge.Val = MergedCellValues.Continue;  
                            }  
                            tableCellProperties.Append(verticalMerge);  
                        }  
                        else  
                        {  
                            run.Append(CreateText(strs[i]));  
                        }  
                        par.Append(run);  
                        cell.Append(tableCellProperties);  
                        cell.Append(par);  
                        row.Append(cell);  
                    }  
                    j++;  
                    table.Append(row);  
                }  
      
                return table;  
            } 

    代码可以简单的多,只是因为有一些要求,比如你表每行是5个数据,但是有一行,数据只有四个,有二个表格合并了,这里会默认把最后二格合并,具体意思大家可以改改代码看.

    好吧,到这里,就差不多,元素添加完后,然后是把相关页面大小的设置加到objBody,最后是添加页眉. 

    public static void AddHeader(MainDocumentPart mainDocPart, ReportImage reportImge)  
            {  
                // 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);  
                  
                ImagePart imagepart = newHeaderPart.AddImagePart(ImagePartType.Jpeg);  
                FileInfo newImg = new FileInfo(reportImge.Value);  
                using (FileStream stream = newImg.OpenRead())  
                {  
                    imagepart.FeedData(stream);  
                }  
                string imageRID = newHeaderPart.GetIdOfPart(imagepart);  
                reportImge.RId = imageRID;  
                Header header = GeneratePageHeaderPart(reportImge);  
                header.Save(newHeaderPart);  
                  
                foreach (SectionProperties sectProperties in  
                  mainDocPart.Document.Descendants<SectionProperties>())  
                {  
                    //  Delete any existing references to headers.  
                    foreach (HeaderReference headerReference in  
                      sectProperties.Descendants<HeaderReference>())  
                        sectProperties.RemoveChild(headerReference);  
                    
                    HeaderReference newHeaderReference =  
                      new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default };  
                    sectProperties.Append(newHeaderReference);  
                }  
                header.Save();  
            }  
      
            // Creates an header instance and adds its children.    
            private static Header GeneratePageHeaderPart(ReportImage reportImge)  
            {  
                var runs = GetRuns(reportImge);  
                Paragraph paragraph = new Paragraph();  
                paragraph.Append(GetParagraphProperties(reportImge));  
                foreach (var run in runs)  
                {  
                    paragraph.Append(run);  
                }  
                paragraph.Append(new Run(new Text() { Text = "" }));  
                Header header = new Header();  
                header.Append(paragraph);  
                return header;  
            } 

    上面的代码主要注意,Image所指的路径存放的和在前面的Document里不一样,这里存放在Header里,从Word文件解压来说,二都是不同的XML文档,你把图片数据写在Document里,得到的标识符在Header是空的.

    好了.OpenXML的主要操作都在这了,但是大家如果想生成这种样式,应该如何处理?

    上面每一个元素如Payload Mass (LBS): 0.22046,就是前面的ReportValue,如何以这种对齐方式来插入了?引入一个新的结构,ReportValueList,主要就是ReportValue的键表信息.

    public static List<Paragraph> GetParagraph(ReportValueList valueList, Int32Value width, int column = 2)  
            {  
                if (column < 1)  
                    column = 1;  
                List<Paragraph> list = new List<Paragraph>();  
                int currentcolumn = 0;  
                Paragraph currentParagraph = null;  
                foreach (var reportvalue in valueList.Values)  
                {  
                    reportvalue.Size = valueList.Size;  
                    if (currentcolumn == 0)  
                    {  
                        currentParagraph = new Paragraph();  
                        ParagraphProperties pPr = new ParagraphProperties();  
                        //添加标签类  
                        Tabs tabs = new Tabs();  
                        Int32Value eachWidth = width / (new Int32Value(column));  
                        for (int i = 1; i < column; i++)  
                        {  
                            TabStop stop = new TabStop();  
                            stop.Val = new EnumValue<TabStopValues>(TabStopValues.Left);  
                            stop.Position = eachWidth * i;  
                            tabs.Append(stop);  
                        }  
                        pPr.Append(tabs);  
                        currentParagraph.Append(pPr);  
                        list.Add(currentParagraph);  
                    }  
                    List<Run> runs = GetRuns(reportvalue);  
                    foreach (var run in runs)  
                    {  
                        currentParagraph.Append(run);  
                    }  
                    currentcolumn++;  
                    if (currentcolumn < column)  
                    {  
                        Run run = new Run();  
                        run.Append(new TabChar());  
                        currentParagraph.Append(run);  
                    }  
                    if (currentcolumn >= column)  
                    {  
                        currentcolumn = 0;  
                    }  
                }  
                return list;  
            }

    主要是对元素TabStop的运用,仔细的大家可以去查查文档

    写到这里,忘记写要用到的命名空间.

    using A = DocumentFormat.OpenXml.Drawing;  
    using PIC = DocumentFormat.OpenXml.Drawing.Pictures;  
    using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;  
    using DocumentFormat.OpenXml;  
    using DocumentFormat.OpenXml.Packaging;  
    using DocumentFormat.OpenXml.Wordprocessing;  

    这个就到这里了.下面如果有时间,我会讲一下,如果对整张报表来进行模版化,意思是在word里的每一个表,一个图片,一个文字,在软件上用生成的结果来替换相应的元素.

    原文地址:https://blog.csdn.net/u011394397/article/details/78142860

  • 相关阅读:
    单例设计静态内部类
    maven中指定jdk编译版本
    带你十天轻松搞定 Go 微服务之大结局(分布式事务)
    微服务从代码到k8s部署应有尽有系列(五、民宿服务)
    微服务从代码到k8s部署应有尽有系列(三、鉴权)
    微服务从代码到k8s部署应有尽有系列(八、各种队列)
    微服务从代码到k8s部署应有尽有系列(七、支付服务)
    微服务从代码到k8s部署应有尽有系列(一)
    带你十天轻松搞定 Go 微服务系列(九、链路追踪)
    微服务从代码到k8s部署应有尽有系列(六、订单服务)
  • 原文地址:https://www.cnblogs.com/mqxs/p/14345332.html
Copyright © 2020-2023  润新知