Дублирование использования документа Word OpenXml и C#

svn status скажет Вам, какие файлы не находятся в SVN, а также что изменяется.

Взгляд свойства SVN для проигнорировать свойства.

Для всех вещей SVN, Красная книга требуется, читая.

10
задан Berkay Turancı 7 December 2012 в 07:46
поделиться

5 ответов

Когда вы смотрите на документ openxml, изменив расширение на zip и открыв его, вы увидите, что эта подпапка word содержит папку _rels, в которой перечислены все отношения. Эти отношения указывают на упомянутые вами части (стиль ...). На самом деле вам нужны эти части, потому что они содержат определение форматирования. Таким образом, отказ от копирования приведет к тому, что новый документ будет использовать форматирование, определенное в файле normal.dot, а не то, которое определено в исходном документе. Так что я думаю, вам придется их скопировать.

-1
ответ дан 3 December 2019 в 18:00
поделиться

Я делал очень похожие вещи, но вместо использования строк подстановки текста я использовал элементы управления содержимым Word. Я задокументировал некоторые детали в следующем сообщении блога, SharePoint и Open Xml . Этот метод не специфичен для SharePoint. Вы можете повторно использовать шаблон в чистом ASP.NET или других приложениях.

Кроме того, я НАСТОЯТЕЛЬНО рекомендую вам просмотреть Блог Эрика Уайта для получения советов, приемов и приемов, касающихся Open Xml. В частности, обратите внимание на манипуляции в памяти с сообщениями Open Xml и сообщениями элементов управления содержимым Word . Я думаю, вы найдете это намного более полезным в долгосрочной перспективе.

Надеюсь, это поможет.

2
ответ дан 3 December 2019 в 18:00
поделиться

В качестве дополнения к вышеизложенному; что, возможно, более полезно, так это поиск элементов управления контентом, которые были помечены (используя слово GUI). Недавно я написал программное обеспечение, которое заполняло шаблоны документов, содержащие элементы управления содержимым с прикрепленными тегами. Их поиск - это просто расширение вышеупомянутого запроса LINQ:

var mainDocument = doc.MainDocumentPart.Document;
var taggedContentControls = from sdt in mainDocument.Descendants<SdtElement>()
                            let sdtPr = sdt.GetFirstChild<SdtProperties>()
                            let tag = (sdtPr == null ? null : sdtPr.GetFirstChild<Tag>())
                            where (tag != null)
                            select new
                            {
                                SdtElem = sdt,
                                TagName = tag.GetAttribute("val", W).Value
                            };   

Я получил этот код откуда-то еще, но не могу вспомнить, где в данный момент; им вся заслуга.

Запрос просто создает объект IEnumerable анонимного типа, который содержит элемент управления содержимым и связанный с ним тег в качестве свойств. Удобно!

2
ответ дан 3 December 2019 в 18:00
поделиться

Большинство разработчиков Java предпочтут видеть getters и setters.

Никто не может разрабатывать код в вашей упаковке, но другие потребляют его. Открывая явно открытый интерфейс, вы можете гарантировать, что внешние потребители используют ваш интерфейс так, как вы ожидаете.

Если вы публично раскрыли внутреннюю реализацию класса:

  • Невозможно помешать потребителям использовать класс ненадлежащим образом
  • Отсутствует контроль над точками входа/выхода; любое публичное поле может быть мутировано в любое время
  • Увеличение связи между внутренней реализацией и внешними потребителями

Поддержание гетеров и установщиков может занять немного больше времени, но предлагает гораздо больше безопасности плюс:

  • Вы можете повторно создать код в любое время, так сильно, как вам захочется, если вы не сломаете общедоступный API (getters, setters и public methods)
  • Модульное тестирование хорошо инкапсулированных классов проще - вы тестируете открытый интерфейс и все (только ваши входы/выходы в «черный ящик»)
  • Наследование, композиция и дизайн интерфейса все будет иметь больше смысла и быть проще в разработке с разъединенными классами
  • Решите, что вам нужно добавить некоторую валидацию к мутатору, прежде чем он будет установлен? Одно хорошее место - внутри установщика.

Вы должны решить, стоит ли преимущества за дополнительное время.

-121--4116883-

Я успешно использовал PortAudio.

Я взял несколько отрывков из моей игрушечной программы, чтобы сделать очень простой «эхо» пример, ниже:

(запустить с наушниками. это цикл обратной связи от микрофона к динамикам и может стать очень громким после нескольких раундов обратной связи)

import Control.Monad (forever)
import Data.Int (Int16)
import Foreign.Ptr (nullPtr)
import Sound.PortAudio

initPortAudio :: Int -> IO (PaStream Int16)
initPortAudio blockSize = do
  Right NoError <- initialize
  Just micDevIdx <- getDefaultInputDevice
  Just spkDevIdx <- getDefaultOutputDevice
  Right paStream <-
    openStream
    (Just (StreamParameters micDevIdx 1 PaInt16 0.1 nullPtr))
    (Just (StreamParameters spkDevIdx 1 PaInt16 0.1 nullPtr))
    44100 blockSize
    :: IO (Either String (PaStream Int16))
  Right NoError <- startStream paStream
  let zeroBlock = replicate blockSize [0]
  Right NoError <- writeStream paStream zeroBlock blockSize
  return paStream

main :: IO ()
main = do
  paStream <- initPortAudio blockSize
  forever $ do
    Right numSampsAvail <- getStreamReadAvailable paStream
    Right curSamps <- readStream paStream 1 numSampsAvail
    Right NoError <- writeStream paStream curSamps numSampsAvail
    return ()
  where
    blockSize = 0x800

Работает здесь в Leopard с GHC 6.10.4.

Моя собственная игрушечная программа фактически использует только вход звука и выводит нули на выход звука (не делая этого PortAudio жалуется).

-121--3723732-

Я придерживаюсь рекомендации Content Controls. Их использование для разметки областей документа, в которых требуется выполнить замещение, является самым простым способом.

Что касается дублирования документа (и сохранения всего содержимого документа, стилей и всего), то это относительно легко:

string documentURL = "full URL to your document";
byte[] docAsArray = File.ReadAllBytes(documentURL);

using (MemoryStream stream = new MemoryStream)
{
    stream.Write(docAsArray, 0, docAsArray.Length);    // THIS performs doc copy
    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
    {
        // perform content control substitution here, making sure to call .Save()
        // on any documents Part's changed.
    }
    File.WriteAllBytes("full URL of your new doc to save, including .docx", stream.ToArray());
}

На самом деле поиск элементов управления содержимым является куском торта с использованием LINQ. Следующий пример находит все элементы управления содержимым Simple Text (которые вводятся как SdtRun):

using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
{                    
    var mainDocument = doc.MainDocumentPart.Document;
    var contentControls = from sdt in mainDocument.Descendants<SdtRun>() select sdt;

    foreach (var cc in contentControls)
    {
        // drill down through the containment hierarchy to get to 
        // the contained <Text> object
        cc.SdtContentRun.GetFirstChild<Run>().GetFirstChild<Text>().Text = "my replacement string";
    }
}

Элементы < Run > и < Text > могут еще не существовать, но их создание является простым:

cc.SdtContentRun.Append(new Run(new Text("my replacement string")));

Надежда, которая помогает кому-либо.: D

5
ответ дан 3 December 2019 в 18:00
поделиться

Этот кусок кода должен скопировать все части из существующего документа в новый.

using (var mainDoc = WordprocessingDocument.Open(@"c:\sourcedoc.docx", false))
using (var resultDoc = WordprocessingDocument.Create(@"c:\newdoc.docx",
  WordprocessingDocumentType.Document))
{
  // copy parts from source document to new document
  foreach (var part in mainDoc.Parts)
    resultDoc.AddPart(part.OpenXmlPart, part.RelationshipId);
  // perform replacements in resultDoc.MainDocumentPart
  // ...
}
14
ответ дан 3 December 2019 в 18:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: