Ответ 1
Может быть, вы должны смотреть на Microsoft.Office.Tools.Word.Document?
Я пытаюсь создать около 600 отчетов в Microsoft Word Word. Документы заполняются данными из базы данных и изображениями, найденными на локальном диске. Я выяснил, что я мог бы создать проект Word Template в visual studio 2010 и запрограммировать шаблон, чтобы при вводе единственного значения (id-number) он автоматически заполнял весь документ.
Я вполне уверен, что это возможно. единственная проблема. Как мне пройти через все записи в базе данных, открыть новый документ на основе шаблона и установить значение id?
for(int i = 0; i < idnumbers.Count(); i++)
{
Word.Application app = new Word.Application();
Word.Document doc = app.Documents.Add(@"C:\..\WordGenerator\bin\Debug\WordTemplate.dotx");
//input the id-number below: HOW??
doc.SaveAs(FileName: @"c:\temp\test.docx");
}
Приложение должно запускаться только один раз, генерируя отчеты, и оно не должно быть быстрым. Это просто должно быть легко развиваться.
Проблема здесь в том, что кажется, что объект DocumentBase недоступен вне проекта Word. Подменю Microsoft.Office.Interop.Word.Document не имеет таких функций, как SelectContentControlsByTitle, что позволяет мне находить и устанавливать мои ContentControls. И это именно то, что мне нужно сделать.
Вот как выглядит мой код сейчас, чтобы вставить текст в мое поле: Приложение Word.Application = новое Word.Application();
Word.Document doc = app.Documents.Add(@"C:\..\test.dotx");
foreach (Word.ContentControl cc in doc.SelectContentControlsByTitle("MyCCTitle"))
{
cc.Range.Text += "1234";
}
doc.SaveAs(FileName: @"c:\temp\test.docx");
Затем обработчик событий в моем шаблоне на BeforeSave заполняет документ на основе текста в объекте под названием MyCCTitle.
Может быть, вы должны смотреть на Microsoft.Office.Tools.Word.Document?
Не используйте Office Automation. Автоматизация офиса открывает экземпляр офиса в фоновом режиме и выполняет действия над ним. Открытие офисного экземпляра 600 раз не кажется очень интересным занятием. (и он никогда не будет работать на стороне сервера)
Посмотрите на Open XML. Вы можете найти множество об этом ниже:
редактировать: Openxmldeveloper закрывается. Вместо этого найдите все источники, упомянутые выше, на http://www.ericwhite.com/.
Вам следует прочитать о формате OpenXML, если вы используете формат Word 2007 или 2010
http://msdn.microsoft.com/en-us/library/bb264572(office.12).aspx
Кажется, здесь есть два вопроса:
Как вы начинаете процесс для определенного значения id
Как вы заполняете документ.
sunilp ответил на Q2. Элементы управления содержимым с привязкой к данным - лучший способ для ввода данных для Word 2007 и более поздних версий.
Фокус OP выглядит Q1.
Нет переключателя командной строки, который позволяет передавать произвольное значение в Word: http://support.microsoft.com/kb/210565
Итак, я вижу, у вас есть 4 варианта:
выполните всю работу через SDK OpenXML, никогда не открывая Word вообще (как предполагали другие плакаты)
создайте минимальный предварительно существующий документ (содержащий номер вашего идентификатора), используя OpenXML SDK, затем откройте Word
автоматизировать Word, чтобы передать номер документа в документ, возможно, как свойство документа
выполните работу по созданию 600 документов в Word с использованием макросов VSTO или Word (VBA)
Me? Я бы создал docx, содержащий связанные с данными элементы управления содержимым в Word, и сохранил его.
Затем, введя мои данные в него как пользовательскую часть xml и сохраните ее. (Этот шаг можно сделать с помощью OpenXML SDK или Word, если вам нужно, чтобы Word обновлял привязки для вашего последующего процесса)
В отношении ответов выше я согласен с J. Vermeire, что OpenXML - это путь. Я уже более трех лет использую инструментарий на базе OpenXML, который создает документы .docx, объединенные с шаблонами и данными базы данных. Ниже приведен пример использования здесь. В этом примере показано, как работать с одним документом в то время, работать с большим количеством из них, просто добавить цикл и вызвать метод для генерации документа.
Добавьте ссылки для Document.OpenXml.dll
и WindowsBase.dll
using System.IO.Packaging;
using DocumentFormat.OpenXml.Packaging;
using System.DirectoryServices;
protected void btnOK_Click(object sender, EventArgs e)
{
try
{
Package package;
string strTemplateName = ddl_Templates.SelectedValue.ToString(); //Select Dotx template
string strClaimNo = "3284112";
string strDatePart = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString();
//Word template file
string templateName = Server.MapPath("~\\LetterTemplates\\" + strTemplateName + ".dotx");
PackagePart documentPart = null;
//New file name to be generated from
string docFileName = Server.MapPath("~\\LetterTemplates\\" + strClaimNo + "_" + strTemplateName + "_" + strDatePart + ".docx");
File.Copy(templateName,docFileName, true);
string fileName = docFileName;
package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
DataSet DS = GetDataSet(strClaimNo, ""); // to get the data from backend to fill in for merge fields
try
{
if (DS != null)
{
if (DS.Tables.Count > 0)
{
if (DS.Tables[0].Rows.Count > 0)
{
foreach (System.IO.Packaging.PackageRelationship documentRelationship
in package.GetRelationshipsByType(documentRelationshipType))
{
NameTable nt = new NameTable();
nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
Uri documentUri = PackUriHelper.ResolvePartUri(
new Uri("/", UriKind.Relative), documentRelationship.TargetUri);
documentPart = package.GetPart(documentUri);
//Get document xml
XmlDocument xdoc = new XmlDocument();
xdoc.Load(documentPart.GetStream(FileMode.Open, FileAccess.Read));
int intMergeFirldCount = xdoc.SelectNodes("//w:t", nsManager).Count;
XmlNodeList nodeList = xdoc.SelectNodes("//w:t", nsManager);
foreach (XmlNode node in nodeList)
{
try
{
xdoc.InnerXml = xdoc.InnerXml.Replace(node.InnerText, DS.Tables[0].Rows[0][node.InnerText.Replace("«", "").Replace("»", "").Trim()].ToString());
}catch(Exception x) { }
}
StreamWriter streamPart = new StreamWriter(documentPart.GetStream(FileMode.Open, FileAccess.Write));
xdoc.Save(streamPart);
streamPart.Close();
package.Flush();
package.Close();
}
using (WordprocessingDocument template = WordprocessingDocument.Open(docFileName, true))
{
template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
template.MainDocumentPart.Document.Save();
}
byte[] bytes = System.IO.File.ReadAllBytes(docFileName);
System.IO.File.Delete(docFileName);
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/vnd.msword.document.12"; //"application/msword";
Response.ContentEncoding = System.Text.Encoding.UTF8;
response.AddHeader("Content-Disposition", "attachment; filename=" + strClaimNo + "_" + strTemplateName + "_" + strDatePart + ".docx;");
response.BinaryWrite(bytes);
response.Flush();
response.Close();
}
else
{
throw (new Exception("No Records Found."));
}
}
else
{
throw (new Exception("No Records Found."));
}
}
else
{
throw (new Exception("No Records Found."));
}
}
catch (Exception ex)
{
package.Flush();
package.Close();
// Softronic to add code for exception handling
}
}
catch (Exception ex)
{
// add code for exception handling
}
finally
{
}
}
foreach (System.IO.Packaging.PackageRelationship documentRelationship in package.GetRelationshipsByType(documentRelationshipType))
каким должен быть documentRelationshipType? это не определено. можете ли вы дать мне знать, что объявить...