سؤال

كنت قادرا على الوصول إلى إشارة مرجعية في word المستند باستخدام هذا الكود:

var res = from bm in mainPart.Document.Body.Descendants<BookmarkStart>()
                              where bm.Name == "BookmarkName"
                              select bm;

الآن أريد أن إدراج فقرة وطاولة بعد هذه المرجعية.كيف أفعل ذلك ؟ (على سبيل المثال رمز سيكون موضع تقدير)

هل كانت مفيدة؟

المحلول

رمز

مرة واحدة لديك المرجعية يمكنك الوصول إلى عنصر الأم و إضافة بنود أخرى بعد ذلك.

using (WordprocessingDocument document = WordprocessingDocument.Open(@"C:\Path\filename.docx", true))
{
    var mainPart = document.MainDocumentPart;
    var res = from bm in mainPart.Document.Body.Descendants<BookmarkStart>()
              where bm.Name == "BookmarkName"
              select bm;
    var bookmark = res.SingleOrDefault();
    if (bookmark != null)
    {
        var parent = bookmark.Parent;   // bookmark's parent element

        // simple paragraph in one declaration
        //Paragraph newParagraph = new Paragraph(new Run(new Text("Hello, World!")));

        // build paragraph piece by piece
        Text text = new Text("Hello, World!");
        Run run = new Run(new RunProperties(new Bold()));
        run.Append(text);
        Paragraph newParagraph = new Paragraph(run);

        // insert after bookmark parent
        parent.InsertAfterSelf(newParagraph);

        var table = new Table(
        new TableProperties(
            new TableStyle() { Val = "TableGrid" },
            new TableWidth() { Width = 0, Type = TableWidthUnitValues.Auto }
            ),
            new TableGrid(
                new GridColumn() { Width = (UInt32Value)1018U },
                new GridColumn() { Width = (UInt32Value)3544U }),
        new TableRow(
            new TableCell(
                new TableCellProperties(
                    new TableCellWidth() { Width = 0, Type = TableWidthUnitValues.Auto }),
                new Paragraph(
                    new Run(
                        new Text("Category Name"))
                )),
            new TableCell(
                new TableCellProperties(
                    new TableCellWidth() { Width = 4788, Type = TableWidthUnitValues.Dxa }),
                new Paragraph(
                    new Run(
                        new Text("Value"))
                ))
        ),
        new TableRow(
            new TableCell(
                new TableCellProperties(
                    new TableCellWidth() { Width = 0, Type = TableWidthUnitValues.Auto }),
                new Paragraph(
                    new Run(
                        new Text("C1"))
                )),
            new TableCell(
                new TableCellProperties(
                    new TableCellWidth() { Width = 0, Type = TableWidthUnitValues.Auto }),
                new Paragraph(
                    new Run(
                        new Text("V1"))
                ))
        ));

        // insert after new paragraph
        newParagraph.InsertAfterSelf(table);
    }

    // close saves all parts and closes the document
    document.Close();
}

رمز أعلاه ينبغي أن تفعل ذلك.ولكن سأوضح بعض الظروف الخاصة.

تكون على علم أنه سوف محاولة الإدراج بعد أن الوالد عنصر من المرجعية.ما هو السلوك الذي تتوقع إذا كانت المرجعية يحدث أن تكون جزءا من الفقرة داخل الجدول ؟ يجب أن إلحاق الفقرة الجديدة والجدول الحق بعد ذلك في هذا الجدول ؟ أو أن يفعل ذلك بعد هذا الجدول ؟

هل يمكن أن يتساءل لماذا الأسئلة أعلاه المسألة.كل هذا يتوقف على المكان الإدراج سوف تحدث.إذا كانت المرجعية الأم في جدول حاليا رمز أعلاه محاولة وضع جدول داخل جدول.هذا جيد, ومع ذلك خطأ قد تحدث بسبب غير صالح OpenXml هيكل.والسبب هو أنه إذا كان إدراج الجدول كان العنصر الأخير في الجدول الأصلي هو TableCell, يجب أن يكون هناك عنصر الفقرة المضافة بعد إغلاق TableCell الوسم.كنت على الفور اكتشاف هذه المشكلة إذا وقعت مرة واحدة قمت بمحاولة فتح المستند في برنامج Word.

الحل هو لتحديد ما إذا كان يتم بالفعل تنفيذ الإدراج في الجدول.

للقيام بذلك, يمكننا أن نضيف إلى ما سبق رمز (بعد الأم فار):

    var parent = bookmark.Parent;   // bookmark's parent element

    // loop till we get the containing element in case bookmark is inside a table etc.
    // keep checking the element's parent and update it till we reach the Body
    var tempParent = bookmark.Parent;
    bool isInTable = false;
    while (tempParent.Parent != mainPart.Document.Body)
    {
        tempParent = tempParent.Parent;
        if (tempParent is Table && !isInTable)
            isInTable = true;
    }

    // ... 

    newParagraph.InsertAfterSelf(table);  // from above sample
    // if bookmark is in a table, add a paragraph after table
    if (isInTable)
        table.InsertAfterSelf(new Paragraph());

أنه يجب منع الخطأ من الحدوث وتعطيك صالح OpenXml.في حين أن حلقة فكرة يمكن أن تستخدم إذا كانت إجابتك "نعم" على سؤالي السابق و يريد إجراء الإدراج بعد الجدول الأصل بدلا من داخل الجدول رمز أعلاه أن تفعل.إذا كان هذا هو الحال ، القضية المذكورة أعلاه لن تكون مصدر قلق و يمكنك استبدال تلك الحلقة و المنطقية التالية:

    var parent = bookmark.Parent;   // bookmark's parent element
    while (parent.Parent != mainPart.Document.Body)
    {
        parent = parent.Parent;
    }

هذا يحافظ إعادة تعيين الوالدين حتى إنه الرئيسية التي تحتوي على عنصر في الجسم المستوى.حتى إذا كانت المرجعية في الفقرة التي في الجدول ، سيكون من الفقرة TableCell إلى الخدمة الاسترداد إلى طاولة المفاوضات ووقف هناك منذ الجدول والد الجسم.في تلك المرحلة الوالدين = الجدول العنصر يمكننا إدراج بعد ذلك.

التي ينبغي أن تغطي بعض مناهج مختلفة ، اعتمادا على الغرض الأصلي.اسمحوا لي أن أعرف إذا كنت بحاجة إلى أي توضيح بعد محاولة ذلك.

الوثيقة عاكس

هل يمكن أن يتساءل كيف تحدد GridColumn.Width القيم.أنا قدمت الجدول وتستخدم الوثيقة عاكس أداة للحصول عليه.عند تثبيت SDK Xml المفتوحة ، أدوات الإنتاجية (إذا قمت بتثبيت لهم) في C:\Program Files\Open XML Format SDK\V2.0\tools (أو ما شابه).

أفضل طريقة لتعلم كيف *.docx يعمل (أو أي فتح Xml تنسيق doc) هو فتح ملف موجود مع الوثيقة عاكس أداة.التنقل في المستند ، حدد العناصر التي تريد إجراء نسخ متماثل.أداة يظهر لك رمز الفعلي المستخدمة لتوليد المستند بأكمله.هذا هو رمز يمكنك نسخ/لصق في التطبيق الخاص بك إلى توليد نتائج مماثلة.يمكنك تجاهل كل مرجع معرفات عادة ؛ عليك أن نلقي نظرة وذلك في محاولة التعود على ذلك.

كما ذكرت أعلاه الجدول رمز تم تكييفها من عينة الوثيقة.لقد تم إضافة جدول بسيط إلى docx, ثم فتحه في أداة نسخ الشفرة التي تم إنشاؤها بواسطة أداة (أنا إزالة بعض الإضافات إلى تنظيفه).أن أعطاني العامل عينة إضافة جدول.

هذا هو مفيدة بشكل خاص عندما كنت تريد أن تعرف كيفية كتابة التعليمات البرمجية التي يولد شيئا ، مثل تنسيق الجداول الفقرات مع أنماط الخ.

نلقي نظرة على هذا الرابط للمزيد من الصور و المعلومات عن الأدوات الأخرى المدرجة في SDK: مقدمة الى XML المفتوحة SDK 2.0.

التعليمات البرمجية المتكررة

كنت قد تكون مهتمة أيضا في التعليمات البرمجية المتكررة على Open Xml.للحصول على قائمة من قصاصات الاختيار هذا بلوق وظيفة.يمكنك تحميلها من هنا: نظام Office 2007 العينة:Open XML Format SDK 2.0 مقتطفات الشفرة ل Visual Studio 2008.

تثبيت مرة واحدة سوف تضيف لهم من الأدوات البرمجية المتكررة مدير القائمة.حدد C# اللغة, انقر فوق الزر إضافة ثم انتقل إلى PersonalFolder\Visual Studio 2008\مقتطفات الشفرة\Visual C#\XML المفتوحة SDK 2.0 Microsoft Office لإضافة لهم.من التعليمات البرمجية الخاصة بك سوف انقر بزر الماوس الأيمن فوق وحدد "إدراج قصاصة" واختيار واحد تريد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top