Unplanned
Last Updated: 14 Jul 2025 13:18 by ADMIN
Daniel
Created on: 02 Jun 2025 06:36
Category: RichTextBox
Type: Bug Report
0
RichTextBox: Document exported to DOCX with 2025 Q2 cannot be opened by 2025 Q1

Document exported to DOCX with 2025 Q2 cannot be opened by 2025 Q1 or previous versions.

 

Workaround: Use document processing to fix the document.

var processing_provider = new Telerik.Windows.Documents.Flow.FormatProviders.Docx.DocxFormatProvider();

var document = processing_provider.Import(File.ReadAllBytes("C:\\Users\\test\\Downloads\\word1.docx"),null);
var bytes_ = processing_provider.Export(document, null);

var rtb_provider = new Telerik.Windows.Documents.FormatProviders.OpenXml.Docx.DocxFormatProvider();
var doc = rtb_provider.Import(bytes_);
radRichTextBox.Document = doc;

4 comments
ADMIN
Martin Ivanov
Posted on: 14 Jul 2025 13:18

Hello Daniel,

Great to hear the suggestion helped. And thank you for sharing your modification.

Regards,
Martin Ivanov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Daniel
Posted on: 11 Jul 2025 21:33

I prefer this workaround since it addresses the problem directly instead of using another FormatProvider that necessitates retesting all our code. 

 

I've modified slightly your code to work in memory with streams instead of using the IO:

 

        public static byte[] FixDocxPaths(byte[] inputDocx)
        {
            using (var memIn = new MemoryStream(inputDocx))
            using (var inputZip = new ZipArchive(memIn, ZipArchiveMode.Read))
            using (var memOut = new MemoryStream())
            {
                using (var outputZip = new ZipArchive(memOut, ZipArchiveMode.Create, true))
                {
                    foreach (var entry in inputZip.Entries)
                    {
                        var newEntry = outputZip.CreateEntry(entry.FullName.Replace("\\", "/"));
                        newEntry.Comment = entry.Comment;

                        using (var inStream = entry.Open())
                        using (var outStream = newEntry.Open())
                        {
                            if (entry.FullName.EndsWith(".rels"))
                                using (var resultStrem = FixRelationships(XDocument.Load(inStream)))
                                    resultStrem.CopyTo(outStream);
                            else
                                inStream.CopyTo(outStream);
                        }
                    }
                }

                memOut.Seek(0, SeekOrigin.Begin);
                return memOut.ToArray();
            }
        }

        private static Stream FixRelationships(XDocument doc)
        {
            XNamespace ns = "http://schemas.openxmlformats.org/package/2006/relationships";

            foreach (var rel in doc.Descendants(ns + "Relationship"))
            {
                var target = rel.Attribute("Target");
                if (target != null && target.Value.Contains('\\'))
                    target.Value = target.Value.Replace("\\", "/");
            }
            var mem = new MemoryStream();
            doc.Save(mem);
            mem.Seek(0, SeekOrigin.Begin);
            return mem;
        }
ADMIN
Martin Ivanov
Posted on: 11 Jul 2025 09:42

Hello Daniel,

This happens because RadWordsProcessing doesn't support the track-changes feature.

In this case, you can use the following workaround. You can open the originally saved .docx file using the .NET ZipFile class and modify its entries. The modification should be in the file paths. Basically, instead of using "\", the paths should use "/". 

public static void FixDocxPaths(string inputDocxPath, string outputDocxPath)
{
   string tempDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
   Directory.CreateDirectory(tempDir);

   using (var archive = ZipFile.OpenRead(inputDocxPath))
   {
	   foreach (var entry in archive.Entries)
	   {
		   string fixedEntryPath = entry.FullName.Replace("\\", "/");
		   string destinationPath = System.IO.Path.Combine(tempDir, fixedEntryPath);

		   Directory.CreateDirectory(System.IO.Path.GetDirectoryName(destinationPath));
		   entry.ExtractToFile(destinationPath, overwrite: true);
	   }
   }
   
   FixRelationships(tempDir);

   if (File.Exists(outputDocxPath)) File.Delete(outputDocxPath);

   using (var zipToCreate = ZipFile.Open(outputDocxPath, ZipArchiveMode.Create))
   {
	   foreach (var filePath in Directory.GetFiles(tempDir, "*", SearchOption.AllDirectories))
	   {
		   string relativePath = System.IO.Path.GetRelativePath(tempDir, filePath).Replace("\\", "/");
		   zipToCreate.CreateEntryFromFile(filePath, relativePath);
	   }
   }
   
   Directory.Delete(tempDir, true);
}

private static void FixRelationships(string root)
{
   foreach (var relFile in Directory.GetFiles(root, "*.rels", SearchOption.AllDirectories))
   {
	   var doc = XDocument.Load(relFile);
	   XNamespace ns = "http://schemas.openxmlformats.org/package/2006/relationships";

	   bool modified = false;
	   foreach (var rel in doc.Descendants(ns + "Relationship"))
	   {
		   var target = rel.Attribute("Target");
		   if (target != null && target.Value.Contains("\\"))
		   {
			   target.Value = target.Value.Replace("\\", "/");
			   modified = true;
		   }
	   }

	   if (modified)
		   doc.Save(relFile);
   }
}


public MainWindow()
{
   InitializeComponent();
   string inputPath = @"../../../not-working-doc.docx";
   string outputPath = @"../../../fixed.docx";
   FixDocxPaths(inputPath, outputPath);
   
   // open the fixed document here
}

Can you try this and let me know if it helps?

Regards,
Martin Ivanov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Daniel
Posted on: 10 Jul 2025 21:44
The workaround doesn't work for us. When using RadFlowDocument, the current implementation of the DocxFormatProvider does not include support for exporting change tracking information (e.g., tracked revisions, insertions, deletions). This means that when you save a document with tracked changes using this provider, the changes will be "finalized" or "accepted" within the DOCX file, and the tracking information will not be preserved.