В Java все находится в форме класса.
Если вы хотите использовать любой объект, тогда у вас есть две фазы:
Пример:
Object a;
a=new Object();
То же самое для концепции массива
Item i[]=new Item[5];
i[0]=new Item();
Если вы не дают секцию инициализации, тогда возникает NullpointerException
.
Я записал немного тестового приложения только что, чтобы сделать это. Мое тестовое приложение работало с документами Word 2003 (.doc) не .docx, но я предполагаю, что процесс является тем же - я должен думать все, что необходимо было бы изменить, должен использовать более новую версию Основного блока Interop. Этот код выглядел бы намного более опрятным с новыми функциями C# 4.0...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Program().Start();
}
private void Start()
{
object fileName = Path.Combine(Environment.CurrentDirectory, @"NewDocument.doc");
File.Delete(fileName.ToString());
try
{
WordApplication = new ApplicationClass();
var doc = WordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing);
try
{
doc.Activate();
AddDocument(@"D:\Projects\WordTests\ConsoleApplication1\Documents\Doc1.doc", doc, false);
AddDocument(@"D:\Projects\WordTests\ConsoleApplication1\Documents\Doc2.doc", doc, true);
doc.SaveAs(ref fileName,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing);
}
finally
{
doc.Close(ref missing, ref missing, ref missing);
}
}
finally
{
WordApplication.Quit(ref missing, ref missing, ref missing);
}
}
private void AddDocument(string path, Document doc, bool lastDocument)
{
object subDocPath = path;
var subDoc = WordApplication.Documents.Open(ref subDocPath, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing);
try
{
object docStart = doc.Content.End - 1;
object docEnd = doc.Content.End;
object start = subDoc.Content.Start;
object end = subDoc.Content.End;
Range rng = doc.Range(ref docStart, ref docEnd);
rng.FormattedText = subDoc.Range(ref start, ref end);
if (!lastDocument)
{
InsertPageBreak(doc);
}
}
finally
{
subDoc.Close(ref missing, ref missing, ref missing);
}
}
private static void InsertPageBreak(Document doc)
{
object docStart = doc.Content.End - 1;
object docEnd = doc.Content.End;
Range rng = doc.Range(ref docStart, ref docEnd);
object pageBreak = WdBreakType.wdPageBreak;
rng.InsertBreak(ref pageBreak);
}
private ApplicationClass WordApplication { get; set; }
private object missing = Type.Missing;
}
}
Вы не должны использовать автоматизацию. Файлы DOCX основаны на Форматах OpenXML. Они - просто zip-файлы с набором XML, и двоичные части (думайте файлы), внутри. Можно открыть их с Упаковочным API (Система. IO.Packaging в WindowsBase.dll), и управляют ими с любым из классов XML в Платформе.
Выезд OpenXMLDeveloper.org для деталей.
Вы хотите использовать AltChunks и OpenXml SDK 1.0 (как минимум, 2.0, если Вы можете). Проверьте блог Eric White для получения дополнительной информации и так же, как большой ресурс!. Вот пример кода, который должен запустить Вас, если не сразу работают.
public void AddAltChunkPart(Stream parentStream, Stream altStream, string altChunkId)
{
//make sure we are at the start of the stream
parentStream.Position = 0;
altStream.Position = 0;
//push the parentStream into a WordProcessing Document
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(parentStream, true))
{
//get the main document part
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
//create an altChunk part by adding a part to the main document part
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(altChunkPartType, altChunkId);
//feed the altChunk stream into the chunk part
chunk.FeedData(altStream);
//create and XElement to represent the new chunk in the document
XElement newChunk = new XElement(altChunk, new XAttribute(relId, altChunkId));
//Add the chunk to the end of the document (search to last paragraph in body and add at the end)
wordDoc.MainDocumentPart.GetXDocument().Root.Element(body).Elements(paragraph).Last().AddAfterSelf(newChunk);
//Finally, save the document
wordDoc.MainDocumentPart.PutXDocument();
}
//reset position of parent stream
parentStream.Position = 0;
}
Его комплекс выхода так код выходит за рамки сообщения форума, я записал бы Ваше Приложение для Вас, но подвести итог.
Я подал заявку в C# для слияния файлов RTF в один документ, я надеюсь, что это должно работать на DOC и файлы DOCX также.
Word._Application wordApp;
Word._Document wordDoc;
object outputFile = outputFileName;
object missing = System.Type.Missing;
object vk_false = false;
object defaultTemplate = defaultWordDocumentTemplate;
object pageBreak = Word.WdBreakType.wdPageBreak;
string[] filesToMerge = new string[pageCounter];
filestoDelete = new string[pageCounter];
for (int i = 0; i < pageCounter; i++)
{
filesToMerge[i] = @"C:\temp\temp" + i.ToString() + ".rtf";
filestoDelete[i] = @"C:\temp\temp" + i.ToString() + ".rtf";
}
try
{
wordDoc = wordApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Word.Selection selection= wordApp.Selection;
foreach (string file in filesToMerge)
{
selection.InsertFile(file,
ref missing,
ref missing,
ref missing,
ref missing);
selection.InsertBreak(ref pageBreak);
}
wordDoc.SaveAs(ref outputFile, ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing);
Hope это помогает!
Несмотря на все представленные хорошие предложения и решения, я разработал альтернативу. На мой взгляд, вам следует полностью избегать использования Word в серверных приложениях. Итак, я работал с OpenXML, но он не работал с AltChunk. Я добавил текст в исходное тело, я получаю список байтов [] вместо списка имен файлов, но вы можете легко изменить код в соответствии с вашими потребностями.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace OfficeMergeControl
{
public class CombineDocs
{
public byte[] OpenAndCombine( IList<byte[]> documents )
{
MemoryStream mainStream = new MemoryStream();
mainStream.Write(documents[0], 0, documents[0].Length);
mainStream.Position = 0;
int pointer = 1;
byte[] ret;
try
{
using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
{
XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);
for (pointer = 1; pointer < documents.Count; pointer++)
{
WordprocessingDocument tempDocument = WordprocessingDocument.Open(new MemoryStream(documents[pointer]), true);
XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);
newBody.Add(tempBody);
mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
mainDocument.MainDocumentPart.Document.Save();
mainDocument.Package.Flush();
}
}
}
catch (OpenXmlPackageException oxmle)
{
throw new OfficeMergeControlException(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), oxmle);
}
catch (Exception e)
{
throw new OfficeMergeControlException(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), e);
}
finally
{
ret = mainStream.ToArray();
mainStream.Close();
mainStream.Dispose();
}
return (ret);
}
}
}
Надеюсь, это вам поможет.