Readdy Write

C# Code: Word Addin mit Fotos verkleinern und einfügen in Word

14.11.2018 (👁23830)

Code: Word Addin mit Fotos verkleinern und einfügen in Word

Das folgende Code Beispiel erstellt ein Word Addin, welches Fotos in eine Word Datei einfügt an einer bestimmten Position oder in einer Tabelle mit einer Zielmarke.

Die Fotos werden unter Windows verkleinert und in eine neue Tabelle hinter der Position Zielmarke eingefügt.

Enthält:

Word Intercom Addin, Ribbonbar

Resize Image Bitmap und Graphics Schnittstelle

DoEvents in Window Forms, WPF, C#

STA Single Thread

 

Mit Einfüge-Dialog

 

Der Software Code ist als Projekt in einer zip Datei im Anhang zum Download

Code Beispiel:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Office.Tools.Ribbon;

 

//----< using >----

//using Microsoft.Office.Tools.Ribbon;        //*word ribbon

using Word = Microsoft.Office.Interop.Word; //*word document

using System.Windows.Forms;                 //*word OpenfileDialog

using Office = Microsoft.Office.Core;       //*lock ratio width height

using Microsoft.Office.Interop.Word;

using System.Threading.Tasks;

using System.Threading;

 

using System.Drawing;           //*compress photo by windows

using System.Drawing.Imaging;   //*compress photo by windows

using System.Drawing.Drawing2D; //*compress quality

 

//----</ using >----

 

namespace Addin_Word_Photos_into_Table

{

    public partial class Ribbon1

    {

        //< init >

        Document _doc = null;

        Word.Application _app = null;

        const string _Table_Key = "Photos_Addin";

        const string _Table_Font = "Arial";

        const int _Table_Font_Size = 11;

        

        //</ init >

 

        //< leeres Delegate erstellen > 

        private delegate void DoEvents_EmptyDelegate();

        //</ leeres Delegate erstellen > 

 

        #region Region: Ribbonbar

        //===================< RibbonBar >===================

        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)

        {

            //tbxPhotos_Tablename.Text = Settings1.Default.Photos_Tablename;            

        }

        //===================</ RibbonBar >===================

        #endregion /Ribbonbar

 

        #region --Button--

        //===================< Buttons >===================

        private void BtnPhotos_Insert_Click(object sender, RibbonControlEventArgs e)

        {

            _doc = Globals.ThisAddIn.Application.ActiveDocument;

            _app = Globals.ThisAddIn.Application;

 

            //< init setup >

            string sInsert_Type = Settings1.Default.Insert_Type;

            string sTargetname = Settings1.Default.Target_Label;

            //</ init setup >

 

            Word.Table table_Photos;

            table_Photos = find_Table_Filled();

            if(table_Photos==null)

            { 

                if (sInsert_Type.IndexOf("Nach Textzeile") >-1)

                { 

                    table_Photos = find_Textline_Create_Empty_Table(sTargetname);

                }

                else

                {

                    table_Photos = find_Table_with_Header(sTargetname);

                }

            }

            if (table_Photos != null)

            {

                insert_Photos_at_Table(table_Photos);

            }

        }

 

 

        //}

 

        private void btnSetup_Click(object sender, RibbonControlEventArgs e)

        {

            frmSetup frm = new frmSetup();

            frm.Show();

        }

        //===================</ Buttons >===================

        #endregion /Buttons

 

 

 

 

        #region --Methods--

        //===================< Methods >===================

        private Word.Table find_Table_Filled()

        {

            //-----------------< find_Table_Filled() >-----------------

 

            //--< find Table Header >--

            //*Loop all tables and ID in Description

            foreach (Word.Table table in _doc.Tables)

            {

                if (table.Rows.Count > 0)

                {

                    if (table.Descr == _Table_Key)

                    {                                

                        return table;

                    }                    

                }

            }

            //< check >

            return null;

            //--</ find Table Header >--

            //-----------------</ find_Table_Filled() >-----------------

        }

 

 

        private Word.Table find_Table_with_Header(string sHeader)

        {

            //-----------------< find_Table_with_Header() >-----------------

 

            //--< find Table Header >--

            //*Loop all tables and look for header

            foreach (Word.Table table in _doc.Tables)

            {

                if (table.Rows.Count > 0)

                {

                    int intColumns_Count = table.Columns.Count;

                    for (int iCol = 1; iCol <= intColumns_Count; iCol++)

                    {

                        //----< @Loop: Columns in Table_Header >----

                        Cell cell = null;

                        try

                        {

                            cell = table.Cell(1, iCol);

                            if (cell.Range.Text.IndexOf(sHeader) == 0)

                            {

                                table.Descr= _Table_Key;

                                return table;

                            }

                        }

                        catch (Exception)

                        {

                            //< endofcolumns >

                            break;

                            //</ endofcolumns >

                        }

                        //----</ @Loop: Columns in Table_Header >----

                    }

                }

            }

            //< check >

            System.Windows.Forms.MessageBox.Show("Tabelle mit Header nicht gefunden. " + Environment.NewLine + "gesuchter Header:" + sHeader, "Header nicht gefunden");

            return null;

            //--</ find Table Header >--

            //-----------------</ find_Table_with_Header() >-----------------

        }

 

 

        private Word.Table find_Textline_Create_Empty_Table(string sHeader)

        {

            //-----------------< find_Table_with_Header() >-----------------

 

 

            //--< find Table Header >--

            //*Loop all tables and look for header

            foreach (Word.Range sLine in _doc.Sentences)

            {

                //-------< Check Sentence >------

                string sText = sLine.Text;

 

                //< check: Zeilenumbruch >

                int posUmbruch = sText.IndexOf("\r");

                if (posUmbruch>0)

                { sText = sText.Substring(0, posUmbruch); }

                posUmbruch = sText.IndexOf("\n");

                if (posUmbruch > 0)

                { sText = sText.Substring(0, posUmbruch); }

                //</ check: Zeilenumbruch >

 

                sText = sText.Trim();

                if (sText == sHeader )

                {

                    //----< Line_found >----

                    sLine.End= sLine.Start+sText.Length;

                    sLine.Select();

                    _app.Selection.Select();

                    _app.Selection.EndKey();

                    sLine.InsertAfter("\n\r");

                    _app.Selection.MoveDown();

                    _app.Selection.MoveDown();

                    Range newRange = _app.Selection.Range;

                    _app.ScreenRefresh();

 

                    //< init setup >

                    int Columns_Count = Settings1.Default.Columns_Count;

                    //</ init setup >

 

                    //< create new table >

                    Word.Table newTable = _doc.Tables.Add( newRange ,NumRows:1,NumColumns: Columns_Count);

                    newTable.Range.Font.Name = _Table_Font;

                    newTable.Range.Font.Size=_Table_Font_Size;

                    newTable.Range.Font.Bold = 0;

                    newTable.Range.Font.Underline = 0;

                    newTable.Descr = _Table_Key;

                    //</ create new table >

 

                    //< out >

                    return newTable;

                    //</ out >

                    //----</ Line_found >----

                }

                //-------</ Check Sentence >------

            }

            //< check >

            System.Windows.Forms.MessageBox.Show("Zeile nicht gefunden. " + Environment.NewLine + "gesuchter Header:" + sHeader, "Header nicht gefunden");

            return null;

            //--</ find Table Header >--

            //-----------------</ find_Table_with_Header() >-----------------

        }

 

        private async void  insert_Photos_at_Table(Word.Table table_Photos)

        {

            //-----------------< insert_Photos_by_TableHeader() >-----------------

 

            //< init >

            int intColumns_count = table_Photos.Columns.Count;

            //</ init >

 

 

 

            //--< Word-FileDialog >--

            OpenFileDialog fileDialog = new OpenFileDialog();

            fileDialog.Filter = "image files (*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.tif;*.tiff)|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.tif;*.tiff";

            fileDialog.Multiselect = true;

            //fileDialog.InitialDirectory = "B:\\2016";

            var result = fileDialog.ShowDialog();

            //--</ Word-FileDialog >--

 

            //< check >

            //*no file

            if (result != System.Windows.Forms.DialogResult.OK)

            { return; }

            //</ check >

 

            //< init setup >

            bool With_Filename = Settings1.Default.Show_Filename;

            bool With_Empty_Line = Settings1.Default.With_Empty_Line;

            int Columns_count = Settings1.Default.Columns_Count;

            string sInsert_Type = Settings1.Default.Insert_Type;

            string Compress_Type = Settings1.Default.Compress_Type;

            //</ init setup >

 

 

 

            //--< check exits Entries >--

            try

            {

                Row row = table_Photos.Rows.Last;

                if (row.Range.InlineShapes.Count > 0)

                {

                    table_Photos.Rows.Add();

                }

            }

            catch (Exception)

            {

            }

            //--</ check exits Entries >--

 

 

 

 

 

            //-------< @Loop: Insert all Images >--------

            int iCol = 0;

            foreach (String sfileName in fileDialog.FileNames)

            {

                //------< Loop.Item  >------

                iCol++;

                if (iCol > 2)

                {

                    iCol = 1;

                    table_Photos.Rows.Add();

                }

                int iRow = table_Photos.Rows.Count;

 

                Cell cell = table_Photos.Cell(iRow, iCol);

                float image_Width = cell.Width - cell.RightPadding - cell.LeftPadding;

                //< get selection >

                Range act_Image_Range = cell.Range;

                //</ get selection >

 

                if(Compress_Type=="Windows")

                { 

                    load_Photo_compressed_to_Clipboard(sfileName, Convert.ToInt32( image_Width));

                    try

                    {

                        act_Image_Range.PasteSpecial(DataType: Word.WdPasteDataType.wdPasteBitmap, 

Placement: Word.WdOLEPlacement.wdInLine, DisplayAsIcon: false, Link: false);

                    }

                    catch (Exception)

                    {

 

                        //throw;

                    }

                    act_Image_Range.Start = act_Image_Range.Start - 1;

                    act_Image_Range.Select();

                    if (act_Image_Range.InlineShapes.Count>0)

                    {

                        

 

                        //< scale >

                        act_Image_Range.InlineShapes[1].LockAspectRatio = Office.MsoTriState.msoTrue;

                        act_Image_Range.InlineShapes[1].Width = image_Width;

                        //</ scale >

                    }

                }

                else

                {

                    //----< Insert Image  >----

                    //< insert picture from Link >

                    Word.InlineShape inlineShape = _doc.InlineShapes.AddPicture(sfileName, LinkToFile: false

SaveWithDocument: true, Range: act_Image_Range);

                    //</ insert picture from Link >

 

                    //< scale >

                    inlineShape.LockAspectRatio = Office.MsoTriState.msoTrue;

                    inlineShape.Width = image_Width;

                    //</ scale >

                    if (Compress_Type == "Word")

                    {

                        //--< replace as png >--

                        //*reduce memory 1 MB to 1kb

                        //< cut >

                        inlineShape.Select();

                        _app.Selection.Cut();

                        //</ cut >

 

                        //*pasteBitmap is much smaller

                        act_Image_Range.PasteSpecial(Link: false, DataType: Word.WdPasteDataType.wdPasteBitmap, 

Placement: Word.WdOLEPlacement.wdInLine, DisplayAsIcon: false);

                        act_Image_Range.Select();

                        //--</ replace as png >--

                    }

                    //----</ Insert Image  >----

                }

                await DoEvents();

 

                //--< Filename >--

                if (With_Filename)

                {

                    int posFilename = sfileName.LastIndexOf("\\");

                    if(posFilename>-1)

                    { 

                        string sFileName_Short = sfileName.Substring(posFilename+1);

                        _app.Selection.Select();

                        _app.Selection.EndKey();

                        _app.Selection.Font.Name = _Table_Font;

                        _app.Selection.Font.Size = _Table_Font_Size;

                        _app.Selection.Font.Bold = 0;

                        _app.Selection.Font.Underline = 0;

                        _app.Selection.TypeParagraph();

                        _app.Selection.TypeText(sFileName_Short);                        

                    }

                }

                //--</ Filename >--

 

                //--< Empty_Line >--

                if (With_Empty_Line)

                {

                    //_app.Selection.EndKey();

                    _app.Selection.TypeParagraph();                     

                }

                //--</ Empty_Line >--

 

                _app.ScreenRefresh();

                _app.ScreenUpdating = true

            }

            //-------</ @Loop: Insert all Images >--------

 

 

            //-----------------</ insert_Photos_at_Table_with_Header() >-----------------

        }

 

        //===================</ Methods >===================

        #endregion /Methods

 

 

 

 

        protected async Task<bool> DoEvents()

 

        {

 

            //----< DoEvents() >---- 

 

            //* Diese Funktion uebernimmt die Unterbrechnung zur Anzeige und Eventbearbeitung in C#, WPF beim langen Loop Berechnungen 

            //* mit einer Dispatcher 

            //* EmptyDelegate im Header definieren 

            //* using System.Windows.Threading; im Header festlegen 

 

 

            //Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new DoEvents_EmptyDelegate(delegate { }));

 

            await System.Threading.Tasks.Task.Run(() => {

 

                Thread.Sleep(1);

 

            });

 

            return true;

 

            //----</ DoEvents() >---- 

 

        }

 

 

        private void load_Photo_compressed_to_Clipboard_old(string sFilename,int setWidth=200)

        {

            // Create a bitmap.

            Bitmap loaded_Bitmap = new Bitmap(sFilename);

 

            // Retrieve the bitmap data from the bitmap.

            BitmapData bitmapData = loaded_Bitmap.LockBits(new System.Drawing.Rectangle(0, 0, loaded_Bitmap.Width, loaded_Bitmap.Height),

ImageLockMode.ReadOnly, loaded_Bitmap.PixelFormat);

 

            float newHeight = setWidth * ((float)loaded_Bitmap.Height / loaded_Bitmap.Width);

            int setHeight = Convert.ToInt32(newHeight);

            //Create a new bitmap.

            Bitmap newBitmap = new Bitmap(200,200, bitmapData.Stride, loaded_Bitmap.PixelFormat, bitmapData.Scan0);

 

            loaded_Bitmap.UnlockBits(bitmapData);

 

            Clipboard.SetImage(newBitmap);

        }

 

 

 

        public static void load_Photo_compressed_to_Clipboard(string input_Image_Path, int setLength)

        {

            //---------------< Image_resize() >---------------

            Bitmap source_Bitmap = new Bitmap(input_Image_Path);

 

            double dblWidth_origial = source_Bitmap.Width;

            double dblHeigth_origial = source_Bitmap.Height;

 

            //< check orientation >

            bool IsOrientation_Horizontal = (dblWidth_origial > dblHeigth_origial) ? true : false;

            //</ check orientation >

 

            int new_Height = 0;

            int new_Width = 0;

            double zoom_factor = 1;

            if (IsOrientation_Horizontal == true)

            {

                new_Width = setLength;

                zoom_factor = new_Width / dblWidth_origial;

                new_Height = (int)(dblHeigth_origial * zoom_factor);

            }

            else

            {

                new_Height = setLength;

                zoom_factor = new_Height / dblHeigth_origial;

                new_Width = (int)(dblWidth_origial * zoom_factor);

            }

 

            Image outImage = new Bitmap(source_Bitmap, new_Width, new_Height);

            var t = new Thread((ThreadStart)(() =>

            {

                Clipboard.SetImage(outImage);

            }));

            t.SetApartmentState(ApartmentState.STA);

            t.Start();

            t.Join();

 

            //---------------</ Image_resize() >---------------

        }

        //----------------------------------</ Class >----------------------------------

 

    }

}

Ribbonbar:

Datei: Ribbon1.cs

Die Ribbonbar ist über den Designer erstellt. Der Code ist hier nicht eingefügt

Datei: Settings1.settings

Settings Setup Code

Datei: frmSetup.cs

Die Einstellungen sind in einem Setup eingefügt.

using System;

using System.Windows.Forms;

 

namespace Addin_Word_Photos_into_Table

{

    public partial class frmSetup : Form

    {

 

        #region Region: Window

        //===================< Region: Window >===================

        public frmSetup()

        {

            InitializeComponent();

 

            //< init >

            tbxTargetlabel.Text= Settings1.Default.Target_Label;

            cbxShow_Photo_Label.Checked= Settings1.Default.Show_Filename;

            ctlInsert_Type.SelectedItem = Settings1.Default.Insert_Type;

            ctlCompress.SelectedItem = Settings1.Default.Compress_Type;

            cbxEmptyLine.Checked= Settings1.Default.With_Empty_Line;

            cbxEmptyLine.Checked=Settings1.Default.With_Empty_Line ;

            ctlColumns.Value= (intSettings1.Default.Columns_Count ;

            //</ init >

        }

        //===================</ Region: Window >===================

        #endregion /Region: Window

 

 

        #region Region: Controls

        //===================< Region: Controls >===================

        private void tbxTargetlabel_TextChanged(object sender, EventArgs e)

        {

            Settings1.Default.Target_Label = tbxTargetlabel.Text;

        }

        private void ctlInsert_Type_SelectedIndexChanged(object sender, EventArgs e)

        {

            Settings1.Default.Insert_Type = ctlInsert_Type.SelectedItem.ToString();

        }

        private void ctlCompress_SelectedIndexChanged(object sender, EventArgs e)

        {

            Settings1.Default.Compress_Type = ctlCompress.SelectedItem.ToString();

        }

 

        private void cbxShow_Photo_Label_CheckedChanged(object sender, EventArgs e)

        {

            Settings1.Default.Show_Filename = cbxShow_Photo_Label.Checked;

        }

 

        private void cbxEmptyLine_CheckedChanged(object sender, EventArgs e)

        {

            Settings1.Default.With_Empty_Line = cbxEmptyLine.Checked;

        }

 

        private void ctlColumns_ValueChanged(object sender, EventArgs e)

        {

            Settings1.Default.Columns_Count = (int) ctlColumns.Value;

        }

 

        //===================</ Region: Controls >===================

        #endregion /Region: Controls

 

 

    }

}


0,00 €