문제

저장 및 인쇄를위한 XPS 문서를 만들고 싶습니다.

내 프로그램에서 XPS 문서 (예 : 일부 데이터가 포함 된 간단한 그리드를 사용하여)를 만들고 전달하는 가장 쉬운 방법은 무엇입니까?

도움이 되었습니까?

해결책

그것에 대해 쉬운 것은 없습니다. 그러나 할 수 있습니다. 메모리에서 문서를 작성하기 위해 내 블로그에 (슬프게도 여전히 버그가 많은) 샘플 코드와 정보가 있습니다.

다음은 모든 것을 캡슐화하는 테스트를 위해 채찍질 한 코드입니다 (메모리의 XPS 문서에 고정 페이지 모음을 작성합니다). 문서를 바이트 배열로 직렬화하기위한 코드가 포함되어 있지만 해당 부분을 건너 뛰고 문서를 반환 할 수 있습니다.

public static byte[] ToXpsDocument(IEnumerable<FixedPage> pages)
{
    // XPS DOCUMENTS MUST BE CREATED ON STA THREADS!!!
    // Note, this is test code, so I don't care about disposing my memory streams
    // You'll have to pay more attention to their lifespan.  You might have to 
    // serialize the xps document and remove the package from the package store 
    // before disposing the stream in order to prevent throwing exceptions
    byte[] retval = null;
    Thread t = new Thread(new ThreadStart(() =>
    {
        // A memory stream backs our document
        MemoryStream ms = new MemoryStream(2048);
        // a package contains all parts of the document
        Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
        // the package store manages packages
        Uri u = new Uri("pack://TemporaryPackageUri.xps");
        PackageStore.AddPackage(u, p);
        // the document uses our package for storage
        XpsDocument doc = new XpsDocument(p, CompressionOption.NotCompressed, u.AbsoluteUri);
        // An xps document is one or more FixedDocuments containing FixedPages
        FixedDocument fDoc = new FixedDocument();
        PageContent pc;
        foreach (var fp in pages)
        {
            // this part of the framework is weak and hopefully will be fixed in 4.0
            pc = new PageContent();
            ((IAddChild)pc).AddChild(fp);
            fDoc.Pages.Add(pc);
        }
        // we use the writer to write the fixed document to the xps document
        XpsDocumentWriter writer;
        writer = XpsDocument.CreateXpsDocumentWriter(doc);
        // The paginator controls page breaks during the writing process
        // its important since xps document content does not flow 
        writer.Write(fDoc.DocumentPaginator);
        // 
        p.Flush();

        // this part serializes the doc to a stream so we can get the bytes
        ms = new MemoryStream();
        var writer = new XpsSerializerFactory().CreateSerializerWriter(ms);
        writer.Write(doc.GetFixedDocumentSequence());

        retval = ms.ToArray();
    }));
    // Instantiating WPF controls on a MTA thread throws exceptions
    t.SetApartmentState(ApartmentState.STA);
    // adjust as needed
    t.Priority = ThreadPriority.AboveNormal;
    t.IsBackground = false;
    t.Start();
    //~five seconds to finish or we bail
    int milli = 0;
    while (buffer == null && milli++ < 5000)
        Thread.Sleep(1);
    //Ditch the thread
    if(t.IsAlive)
        t.Abort();
    // If we time out, we return null.
    return retval;
}

엉뚱한 스레딩 코드에 유의하십시오. MTA 스레드에서는 이것을 할 수 없습니다. 당신이 STA 스레드에 있다면 당신은 그것을 제거 할 수 있습니다.

다른 팁

.NET (v2 이상)에서 작업하는 경우 WPF Visual에서 유효한 XPS 문서를 매우 쉽게 생성 할 수 있습니다.

예를 들어,이 블로그 게시물을 살펴보십시오.

http://nixps.blogspot.com/2008/12/wpf-to-pdf.html

예에서는 추가 처리를 수행하기 전에 WPF Visual을 생성하고 XPS 파일로 변환합니다.

.NET에서 일하지 않거나 XPS 출력에 대한 더 많은 제어를 원한다면 라이브러리를 사용하는 것이 좋습니다 (예 : NIXPS SDK) 이것을 위해. 코딩하기가 훨씬 쉽고 XML 구성을 스스로 작성하는 것 (및 적절한 자원 관리 등)보다 오류가 훨씬 적습니다.

전부는 정말 XML입니다. XML 파일로 작업하는 것이 편한 경우 XPS 문서를 사용하는 데 아무런 문제가 없어야합니다. 다음은 과거에 내가 시작하기 위해 사용한 간단한 튜토리얼입니다.

http://blogs.ocrasoft.nl/jeroenveurink/?p=21

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top