WinForms/WPF 뷰어에서 DOCX 페이지의 지연 로딩

블로그 카테고리:이미징오피스.NET

2024/04/19

DOCX 문서는 텍스트, 이미지, 그래픽 등을 포함하는 Microsoft Word의 Open XML 형식 문서입니다. DOCX 문서의 장점은 내용을 간단하고 직관적으로 편집할 수 있다는 것입니다. DOCX 문서의 단점은 문서 내용을 페이지로 나누기 위해 레이아웃을 지정해야 한다는 것입니다. 즉, 1000페이지 분량의 DOCX 문서의 경우 마지막 페이지만 보더라도 모든 페이지를 렌더링해야 합니다.

Microsoft Office Word에서 페이지 수가 많은 DOCX 문서(1000페이지 이상)를 열면 Word가 DOCX 문서를 거의 즉시 열고 몇 페이지(3~5페이지)만 표시하는 것을 알 수 있습니다. 그 후 Word는 백그라운드에서 문서의 나머지 페이지를 모두 로드합니다. 이는 Word가 DOCX 문서의 모든 페이지를 로드하는 데 걸리는 시간을 줄이기 위한 것입니다. 백그라운드 페이지 로딩 기능은 사용자가 문서의 앞부분을 빠르게 보고 편집할 수 있도록 해주기 때문에 매우 편리합니다. 다만, 문서의 마지막 페이지를 보거나 편집해야 하는 경우에는 Word가 문서의 모든 페이지를 로드할 때까지 기다려야 합니다.

VintaSoft Imaging .NET SDK는 DOCX 문서를 볼 수 있도록 지원하며, 기본적으로 SDK는 DOCX 문서의 모든 페이지에 대한 정보를 가져온 후에야 문서 뷰어에서 DOCX 문서의 페이지를 볼 수 있습니다. 페이지 수가 많은 DOCX 문서(1000페이지 이상)의 경우, 모든 페이지에 대한 정보가 가져와질 때까지 기다려야 하므로 페이지 보기가 불편합니다.

또한 VintaSoft Imaging .NET SDK는 Microsoft Office Word의 동작, 즉 DOCX 문서의 페이지 정보를 백그라운드에서 가져오는 기능을 재현할 수 있도록 합니다. 이미지 컬렉션의 페이지/이미지에 대한 정보를 백그라운드에서 가져오려면 [ImageViewerImagesManager] 클래스를 사용하고 해당 클래스가 다음을 수행해야 함을 지정해야 합니다.

다음은 DOCX 문서 페이지에 대한 정보를 백그라운드에서 로드하는 동안 문서 뷰어에 DOCX 문서 페이지를 표시할 수 있는 C# 코드입니다.
/// <summary>
/// The images manager for an image viewer.
/// </summary>
Vintasoft.Imaging.UI.ImageViewerImagesManager _imagesManager;



/// <summary>
/// Initializes a new instance of the <see cref="MainForm1"/> class.
/// </summary>
public MainForm1()
{
    InitializeComponent();

    // create images manager
    _imagesManager = new Vintasoft.Imaging.UI.ImageViewerImagesManager(imageViewer1);
    // specify that manager should retrieve information about image from file during 1 second, add images to an image viewer,
    // do previous steps until information about all images will not be retrieved
    _imagesManager.IntermediateAddInterval = 1000;
    // specify that manager should work asynchronously
    _imagesManager.IsAsync = true;
    _imagesManager.ImageSourceAddException += ImagesManager_ImageSourceAddException;
}



/// <summary>
/// Opens an image file.
/// </summary>
/// <param name="filename">The filename.</param>
internal void OpenImageFile(string filename)
{
    // cancel previous file opening process
    CancelOpening();
    // clear image collection of manager
    _imagesManager.Images.ClearAndDisposeItems();
    // add image file to the manager
    _imagesManager.Add(filename);
}

/// <summary>
/// Cancels the opening of a file.
/// </summary>
private void CancelOpening()
{
    _imagesManager.Cancel();
}

private void ImagesManager_ImageSourceAddException(object sender, Vintasoft.Imaging.ImageSourceExceptionEventArgs e)
{
    string message = string.Format("Cannot open {0} : {1}", System.IO.Path.GetFileName(e.SourceFilename), e.Exception.Message);
    System.Windows.Forms.MessageBox.Show(message, "Error");
}